Python: более читаемое понимание списка
Я новичок в Python. У меня есть следующий код, который является частью строкового алгоритма, который я сейчас разрабатываю.
>>> newlist=[]
>>> i =0
>>> for x in range(len(list1)):
new_item = [y for y in list1[i] if y not in list2[i]]
newlist.append(new_item)
i=i+1
>>> print newlist
Мне нравится делать это, используя понимание списка, поскольку я прочитал, что это оптимизировано по производительности. Может кто-нибудь предложить мне метод.
Спасибо.
[Редактировать]
пример:
list1= [[['pat'],['cut'],['rat']], [['sat','pat'],['cut','pat']],[['instructor','plb','error0992'],['instruction','address','00x0993'],['data','address','017x112']]
list2= [[['pat'], ['cut'], ['rat']], [['sat', 'pat']], [['instructor', 'plb', 'error0992'], ['instruction', 'address', '00x0993']]]
Итак, новый список,
newlist= [[], [['cut', 'pat']], [['data', 'address', '017x112']]]
3 ответа
Если вы просто хотите, чтобы все элементы были в одном списке, а не в другом, я бы посоветовал заглянуть в python set
s. Они не допускают дублирования, но преимущества в производительности и удобочитаемости велики.
Вы бы реализовали это так:
newlist = list(set(list1).difference(set(list2)))
Если вы хотите применить это вместо ваших текущих решений, вы должны сделать что-то в соответствии с тем, что предложил Доминик (слегка отредактировано для удобства чтения):
[list(set(a)-set(b)) for a, b in zip(list1, list2)]
Если порядок имеет значение или у вас есть дубликаты, то понимание единого списка, которое вы имели выше, должно сработать, просто оберните его как лямбда-функцию, чтобы сделать его более читабельным:
single_item = lambda i: [y for y in list1[i] if y not in list2[i]]
newlist = [single_item(i) for i in enumerate(list1)]
Это понимание вложенного списка, которое делает то же самое, что и ваш код (хотя и не сохранит значение i
).
newlist = [[y for y in list1[i] if y not in list2[i]] for i in range(len(list1))]
TL;DR: [[y for y in list1[i] if j not in list2[i]] for i in enumerate(list1)]
Вы должны использовать enumerate
вместо range(len())
не-идиомы. Вы также можете рассмотреть возможность создания выражения-генератора. Либо с конкретным вложенным списком:
([y for y in list1[i] if j not in list2[i]] for i in enumerate(list1))
или нет
((y for y in list1[i] if j not in list2[i]) for i in enumerate(list1))