Имате проблеми с pythonic стила и разбирането на списъка

Прекарах вчера в писане на малък скрипт на Python, който не е основният ми език, и това ме остави с някои въпроси за това как да правя нещата в правилния "pythonic" стил. Задачата е доста проста, имам два масива 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(), който създава нов списък с компресирани списъци, можете да предприемете „итеративен“ подход и да използвате itertools.izip():

>>> 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