Проблемы с питоническим стилем и пониманием списка

Вчера я написал небольшой скрипт на Python, который не является моим основным языком, и у меня остались вопросы о том, как делать что-то в правильном «питоническом» стиле. Задача довольно простая, у меня есть два массива fieldnames и values. Представьте, что их содержимое

fieldnames = ['apples','oranges','pears','bananas']
values = [None,2,None,5]

Мне нужно создать массив имен полей, состоящий только из индексов, соответствующих значениям, отличным от None. Сейчас делаю так:

#print fieldnames
usedFieldnames = []

for idx,val in enumerate(values):
    if val is not None:
        usedFieldnames.append(fieldnames[idx])

Я мог ошибаться, но мне это кажется очень непифоническим, и мне было интересно, есть ли более подходящий для Python способ сделать это с пониманием списка. Любая помощь будет оценена по достоинству.


person alayers2    schedule 23.04.2014    source источник


Ответы (3)


Вы можете использовать enumerate для перебора списка и одновременного получения индекса текущего элемента.

print [idx for idx, field in enumerate(fieldnames) if values[idx] is not None]
# [1, 3]

Если вам нужны имена полей, тогда

print [field for idx, field in enumerate(fieldnames) if values[idx] is not None]
# ['oranges', 'bananas']
person thefourtheye    schedule 23.04.2014
comment
@alecxe Спасибо :) Обновил свой ответ. - person thefourtheye; 23.04.2014

Вы можете использовать zip():

>>> fieldnames = ['apples','oranges','pears','bananas']
>>> values = [None,2,None,5]
>>> [field for field, value in zip(fieldnames, values) if value is not None]
['oranges', 'bananas']

Если вы используете python2.x вместо zip(), который создает новый список с заархивированными списками, вы можете использовать «итеративный» подход и использовать _ 4_:

>>> from itertools import izip
>>> [field for field, value in izip(fieldnames, values) if value is not None]
['oranges', 'bananas']

В случае python3.x zip() возвращает итератор, а не список.

person alecxe    schedule 23.04.2014
comment
Вы бы сказали, что zip в этом случае создает ненужный список? - person C.B.; 23.04.2014
comment
Возможно, вы захотите использовать izip - person thefourtheye; 23.04.2014
comment
Помните, что zip не создает ненужный список, если вы используете Python 3, и новичкам, вероятно, в любом случае следует использовать 3. - person DSM; 23.04.2014
comment
В большинстве случаев оптимизация использования itertools.izip является преждевременной / ненужной. - person Erik Kaplun; 23.04.2014

Пример хранения четных чисел в списке с использованием понимания списка в python3:

even_number_collection = [ num for num in range(20) if num%2==0]

# one way to print above list
print(*even_number_collection,sep=" ")

# another way
for a in even_number_collection:
    print(a, end=" ")

Вы можете прочитать здесь https://www.geeksforgeeks.org/python-list-comprehension-and-slicing/

person Brijesh Kushwaha    schedule 02.04.2018