Чому “return list.sort ()” повертає None, не список?


155

Мені вдалося переконатись, що findUniqueWordsрезультат призводить до сортування list. Однак список не повертається. Чому?

def findUniqueWords(theList):
    newList = []
    words = []

    # Read a line at a time
    for item in theList:

        # Remove any punctuation from the line
        cleaned = cleanUp(item)

        # Split the line into separate words
        words = cleaned.split()

        # Evaluate each word
        for word in words:

            # Count each unique word
            if word not in newList:
                newList.append(word)

    answer = newList.sort()
    return answer

Я не думаю, що вам потрібно багато разів перетворювати елемент у рядок. Одного разу зазвичай достатньо, і це чистіше робити це на вході, щоб очистити також.
Бен

3
Просто дурна думка, але якщо ви хочете список унікальних предметів, чому б вам просто не перетворити їх у набір? Потім ви можете перетворити їх назад у список, якщо вам потрібно. theSet= set(theList) І ви закінчили, вам потрібно лише повернути його до списку: theList = list(theSet) Готово. Легко.
runlevel0

1
Додавши до сказаного @ runlevel0 (що є гарною ідеєю): Ви можете перетворити theSet' into a sorted list with відсортований (theSet) `.
Заз

дуже нерегулярна мова
Ніколас

Це стрижневий, але проблематичний / дратуючий, філософський вибір мови. Прив’язання загалом - це сирота в пітоні.
javadba

Відповіді:


195

list.sortсортує список за місцем, тобто він не повертає новий список. Просто напишіть

newList.sort()
return newList

18
return sorted(newList)коротше. Тут не має значення, оскільки змінна є локальною, але на місці сортування може змінити загальну змінну в деяких випадках.
Жан-Франсуа Фабре

Цікаво, що якщо до списку додано запис a.append('x'), або a.extend('x)ви також не можете зв'язати ланцюжок sort()у кінці. Його треба розділити на 2 рядки. Було б приємніше, якби методи повернули список! docs.python.org/3/tutorial/datastructures.html Це ж повідомлення покусало мене, зробивши саме це. Отже, вам потрібно розбити річ на два рядки, після цього ви повинні використовувати .sort() НЕ sorted() в списку, оскільки це генерує ту саму помилку l = ['1']; l = sorted(l.append('2'))(я щойно додав
напівкрапку,

Я також додам, що, можливо, варто поглянути на це: grantjenks.com/docs/sortedcontainers , github.com/grantjenks/python-sortedcontainers По-моєму, я вже думав про рефакторинг зі списку до набору, оскільки я цього не зробив хочете дублікатів, а потім шукали реалізацію SortedSet, і так і не знайшли в колекціях модуль ... Джерело: stackoverflow.com/questions/5953205 / ...
JGFMK

3
Чомуsort функція була розроблена таким чином? чи є якісь накладні показники та інші недоліки, якщо повернути відсортований список замість None?
Лей Ян

1
Я також зіткнувся з наступною проблемою: print(newList.sort())дав None. Однак коли я це зробив, newList.sort()і тоді print(newList)це спрацювало.
Коць

136

Проблема тут:

answer = newList.sort()

sortне повертає відсортований список; швидше, він сортує список за місцем.

Використання:

answer = sorted(newList)

5
Це те, що найбільше знадобиться: різниця між list.sort()і sorted(list).
geekoverdose

62

Ось електронний лист від Гвідо ван Россума у ​​списку розробок Python, в якому пояснюється, чому він вирішив не повертатись selfна операції, які впливають на об’єкт, і не повертають нову.

Це походить від стилю кодування (популярного в різних інших мовах, я вважаю, що особливо це стосується Lisp), де низка побічних ефектів на одному об'єкті може бути пов'язана таким чином:

 x.compress().chop(y).sort(z)

що було б те саме

  x.compress()
  x.chop(y)
  x.sort(z)

Я вважаю, що ланцюжок утворює загрозу для читабельності; це вимагає, щоб читач був глибоко знайомий з кожним із методів. Друга форма дає зрозуміти, що кожен з цих викликів діє на один і той же об’єкт, і тому навіть якщо ви не дуже добре знаєте клас та його методи, ви можете зрозуміти, що другий та третій виклики застосовуються до x (і що всі дзвінки робляться для їх побічних ефектів), а не до чогось іншого.

Я хотів би зарезервувати ланцюжок для операцій, які повертають нові значення, як-от операції обробки рядків:

 y = x.rstrip("\n").split(":").lower()

33
Забавно, split(":").lower()це поганий ланцюжок, оскільки splitповертає список, у якому немає lowerметоду.
SuperBiasedMan

14

Python звично повертається Noneз функцій та методів, які мутують дані, такі як list.sort, list.appendі random.shuffle, маючи на увазі, що він натякає на те, що він мутував.

Якщо ви хочете взяти ітерабельний і повернути новий, відсортований список його елементів, скористайтеся sortedвбудованою функцією.


14

У Python є два види сортування: метод сортування (або "членська функція") та функція сортування . Метод сортування діє на вміст названого об'єкта - подумайте про це як про дію, яку об'єкт здійснює, щоб переупорядкувати себе . Функція сортування - це операція над даними, представленими об'єктом і повертає новий новий об'єкт з тим самим вмістом у відсортованому порядку.

З урахуванням списку цілих чисел, названих lсамим, список буде перепорядкований, якщо ми зателефонуємо l.sort():

>>> l = [1, 5, 2341, 467, 213, 123]
>>> l.sort()
>>> l
[1, 5, 123, 213, 467, 2341]

Цей метод не має зворотного значення. Але що робити, якщо ми спробуємо призначити результат l.sort()?

>>> l = [1, 5, 2341, 467, 213, 123]
>>> r = l.sort()
>>> print(r)
None

rтепер рівне насправді нічого. Це одна з тих дивних, дещо дратівливих деталей, про яку програміст, ймовірно, забуде після періоду відсутності в Python (саме тому я це пишу, тому я не забуваю знову).

Функція sorted(), з іншого боку, нічого не зробить до вмісту l, але поверне новий, відсортований список із тим самим вмістом, що і l:

>>> l = [1, 5, 2341, 467, 213, 123]
>>> r = sorted(l)
>>> l
[1, 5, 2341, 467, 213, 123]
>>> r
[1, 5, 123, 213, 467, 2341]

Майте на увазі, що повернене значення не є глибокою копією , тому будьте обережні щодо побічних операцій над елементами, що містяться в списку, як зазвичай:

>>> spam = [8, 2, 4, 7]
>>> eggs = [3, 1, 4, 5]
>>> l = [spam, eggs]
>>> r = sorted(l)
>>> l
[[8, 2, 4, 7], [3, 1, 4, 5]]
>>> r
[[3, 1, 4, 5], [8, 2, 4, 7]]
>>> spam.sort()
>>> eggs.sort()
>>> l
[[2, 4, 7, 8], [1, 3, 4, 5]]
>>> r
[[1, 3, 4, 5], [2, 4, 7, 8]]

4

Щоб зрозуміти, чому він не повертає список:

sort () не повертає жодного значення, тоді як метод sort () просто сортує елементи заданого списку в певному порядку - висхідний чи низхідний не повертаючи жодного значення.

Тому проблема полягає в тому, answer = newList.sort()де відповіді немає.

Натомість ви можете просто зробити return newList.sort() .

Синтаксис методу sort ():

list.sort(key=..., reverse=...)

Крім того, ви можете також використовувати вбудовану функцію Python, відсортовану () для тих же цілей.

sorted(list, key=..., reverse=...)

Примітка: Найпростіша різниця між sort () та sorted () полягає у: sort () не повертає жодного значення, а sorted () повертає список, який можна повторити.

Так у вашому випадку answer = sorted(newList).


0

ви можете використовувати метод sorted (), якщо ви хочете, щоб він повернув відсортований список. Це зручніше.

l1 = []
n = int(input())

for i in range(n):
  user = int(input())
  l1.append(user)
sorted(l1,reverse=True)

Метод list.sort () змінює список на місці та повертає None.

якщо ви все ще хочете використовувати сортування, ви можете це зробити.

l1 = []
n = int(input())

for i in range(n):
  user = int(input())
  l1.append(user)
l1.sort(reverse=True)
print(l1)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.