2013-03-15 3 views
3

Edit: Я использую Python 2.7Сравните несколько уникальных строк в списке

У меня есть данность «матрица», как показано ниже, которая содержит несколько списков строк. Я хочу отсортировать матрицу и распечатать только строки (строки), содержащие только определенный набор строк.

Может ли кто-нибудь дать мне подсказку о том, как это сделать?

То, что я пытался до сих пор:

matrix = [("One", "Two", "Three"), 
("Four", "Five", "Six"), 
("Seven", "Eight", "One"), 
("Four", "Five", "Six"), 
("One", "Three", "Six")] 

for index, data in enumerate(matrix): 
    if "One" and "Three" and "Six" in data: 
     print data 

желаемый результат:

("One", "Three", "Six") 

фактический объем производства (как сейчас):

('Four', 'Five', 'Six') 
('Four', 'Five', 'Six') 
('One', 'Three', 'Six') 

ответ

8

Ваш тест неверен, вы хотите для проверки каждой строки отдельно с помощью in:

if "One" in data and "Three" in data and "Six" in data: 

and не группирует операнды для теста in; каждый компонент оценивается отдельно:

("One") and ("Three") and ("Six" in data): 

, что приводит к результату "Six" in data возвращается; остальные два значения всегда являются True, поскольку они являются непустыми строками.

Лучше подход заключается в использовании set:

if {"One", "Three", "Six"}.issubset(data): 
+0

Это сделало, спасибо. – Hoser

0

Причиной этого является то, что вы злоупотребляя and

попробовать

"One" and "Three" 

в интерактивной консоли - это было бы вывод True, потому что «One» и «Three» являются «cast» tobooleans, и они рассматриваются как истинные значения. Таким образом, для этой работы вы должны переписать условие

if "One" in data and "Three" in data and "Six" in data 
+0

'' One 'и' Three'' на самом деле возвращает '' Three'', потому что '' One'' оценивает (он не отличен от boolean) до True, поэтому возвращаемое значение является вторым операндом 'and'. – poke

2

Я хотел бы использовать наборы для этого:

matrix = [("One", "Two", "Three"), 
("Four", "Five", "Six"), 
("Seven", "Eight", "One"), 
("Four", "Five", "Six"), 
("One", "Three", "Six")] 

target = {"One", "Three", "Six"} 

for row in matrix: 
    if target <= set(row): 
     print row 

Здесь target <= set(row) проверяет target является ли подмножество set(row).

Причины ваш код не работает в том, что следующий:

if "One" and "Three" and "Six" in data: 

эквивалентен:

if bool("One") and bool("Three") and ("Six" in data): 

С bool("One") и bool("Three") является True, все выражение просто проверяет, является ли "Six" является в data.

0

Почему вы не проверить его в комплекте:

for data in matrix: 
    if set(["Three","Six","One"]).issubset(set(data)): 
     print data 

приводит:

('One', 'Three', 'Six'). 

Обратите внимание, что, как вы проверяете как набор существует проблема с упорядочением.

0

На самом деле, с if заявлением

if "One" and "Three" and "Six" in data: 

вы получает весь список, который содержит Six (заметить ваш выход)

("Seven", "Eight", "One") и ("One", "Two", "Three") не печатаются, потому что Six не в вас кортежах:

Кроме того, каждая строка (не ""), если true в python для Пример:

>>> if("One"): 
...  print "Yes" 
... else: 
...  print "No" 
... 
Yes 

Таким образом, вы, если выражение

if "One" and "Three" and "Six" in data: 

эквивалентно

if True and True and "Six" in data: 

, что эквивалентно:

if "Six" in data: 

Где, как вам нужно, где "один" , «Три» и «Шесть» присутствуют, так что:

if (("One" in data) and 
     ("Three" in data) and 
     ("Six" in data) 
    ): 

Как ответил @Martijn Pieters. Кроме того, получите еще одну технику:

>>> target = {"One", "Three", "Six"} 
>>> for data in matrix: 
...  if (set(map(tuple, data)) <= set(map(tuple, target))): 
...    print data 
... 
('One', 'Three', 'Six') 
>>> 
Смежные вопросы