2014-11-23 2 views
3
list1 = ['Hello', 10, None] 
list2 = [g.lower() for g in list1 if isinstance(g, str)] 
list3 = [g.lower() if isinstance(g,str) else g for g in list1] 
list4 = [isinstance(g, str) and g.lower() or g for g in list1] 

Если я хочу, чтобы преобразовать строку в list в нижнем регистре, можно использовать метод, описанный в list2 и выход будет ['hello'].Как это понимание списка работает?

В дополнении к этому преобразованию, если я хочу сохранить целые числа (что 10 в данном случае) и None метода в обоих list3 и list4 будет работать и на выходе будет ['hello', 10, None].

Мой вопрос в том, что я не могу понять, как работает метод в list4.

+2

Не используйте 'list' как имя. 'list' - встроенная функция, и вам лучше оставить ее в покое. – gboffi

+0

@gboffi Итак, список, str, dict, кортеж и т. Д. Все встроенные функции? –

+0

Пожалуйста, разместите фактический код, который вы используете. В соответствии с этим строка 2 должна дать вам ошибку – inspectorG4dget

ответ

4

Для начала написания кода, как это:

condition and value1 or value2 

был, как люди реализовали трехкомпонентный условный оператор в Python до:

value1 if condition else value2 

conditional expression был введен в версии 2.5 из-за PEP 0308. Использование старого метода теперь устарело в пользу немного более эффективного и гораздо более читаемого более нового метода.


старый метод работает, потому что, как and и or работать в Python. Вместо того, чтобы возвращать логические результаты, как на большинстве других языков, эти операторы возвращают значения.

Выполнение a and b возвращает a, если a - False; в противном случае она возвращает b:

>>> 0 and 1 
0 
>>> 1 and 0 
0 
>>> 1 and 2 
2 
>>> 

Ведение a or b возвращает a если a вычисляется в True; в противном случае она возвращает b:

>>> 1 or 0 
1 
>>> 0 or 1 
1 
>>> 1 or 2 
1 
>>> 

Кроме того, в случае, если вы не знаете, 0 вычисляет False в то время как каждый номер имеет значение True.


Далее в коде, это:

isinstance(g, str) and g.lower() or g 

на самом деле интерпретируется Python как:

(isinstance(g, str) and g.lower()) or g 

Теперь, если isinstance(g, str) возвращает False (g не является строкой):

(False and g.lower()) or g 

False возвращается and:

False or g 

и затем возвращается org. Таким образом, мы избегали вызова .lower() по нестрочному типу.

Если, однако, isinstance(g, str) возвращает True (g является строкой):

(True and g.lower()) or g 

and возвращает g.lower():

g.lower() or g 

, а затем возвращает org.lower(), и это хорошо, потому что g является строкой.


Подвела, эти два выражения:

g.lower() if isinstance(g,str) else g 

isinstance(g, str) and g.lower() or g 

функционально эквивалентны. Но, пожалуйста, используйте первый! Другое ужасно для удобочитаемости.

1

the doc Цитирование:

Выражение x and y сначала вычисляет x; если x является ложным, возвращается его значение ; в противном случае вычисляется y и возвращается итоговое значение .

Выражение x or y оценивает x; if x is true, его значение равно ; в противном случае оценивается y и возвращается итоговое значение .

Из-за правил приоритета, isinstance(g, str) and g.lower() or g фактически оценивается как (isinstance(g, str) and g.lower()) or g (умножение имеет более высокий приоритет, чем сложение).

Это в основном означает следующее:

  • если isinstance(g, str) верно, будет принято результат g.lower()
  • иначе g будут приняты

Как вы видите, это то же самое, что у вас есть в list3 операции.

Смежные вопросы