Почему «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
Lee_Str
источник
Я не думаю, что вам нужно много раз превращать элемент в строку. Как правило, достаточно одного раза, и это будет чище, чтобы сделать это на входе для очистки.
Бен
3
Просто глупая мысль, но если вам нужен список уникальных предметов, почему бы вам просто не конвертировать в набор? Затем вы можете преобразовать их обратно в список, если вам нужно. theSet= set(theList) И все готово, вам нужно только привести его обратно к списку: theList = list(theSet) Готово. Легко.
runlevel0
1
Добавление к тому, что сказал @ runlevel0 (что является хорошей идеей): Вы можете преобразовать theSet' into a sorted list with отсортированный (theSet) `.
Zaz
очень нерегулярный язык
Николас
Это основной - но проблемный / раздражающий - философский выбор языка. Цепочка в целом является осиротевшей концепцией в питоне.
Джавадба

Ответы:

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() NOT 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)
NPE
источник
5
Это то, что больше всего понадобится: разница между list.sort()и sorted(list).
geekoverdose
62

Вот электронное письмо от Гвидо ван Россума из списка разработчиков Python, объясняющее, почему он решил не возвращаться selfк операциям, которые влияют на объект, и не возвращать новый.

Это происходит от стиля кодирования (популярного в различных других языках, я полагаю, особенно в этом пользуется Лисп), где ряд побочных эффектов на один объект может быть прикован цепью следующим образом:

 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 имеет два вида сортировки: метод сортировки (или «функция-член») и функция сортировки . Метод sort работает с содержимым названного объекта - думайте о нем как о действии, которое объект предпринимает, чтобы изменить порядок себя . Функция сортировки представляет собой операцию над данными, представленными объектом, и возвращает новый объект с тем же содержимым в отсортированном порядке.

При заданном списке целых чисел 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]]
zxq9
источник
4

Чтобы понять, почему он не возвращает список:

сортировать () не возвращает никакого значения , а вид () метод просто сортирует элементы данного списка в определенном порядке - по возрастанию или по убыванию без возвращения никакого значения.

Так что проблема в том, answer = newList.sort()где нет ответа.

Вместо этого вы можете просто сделать return newList.sort().

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

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

Кроме того, вы также можете использовать встроенную функцию Python sorted () для той же цели.

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)
user8153007
источник