2015-09-12 6 views
2

Я новичок в программировании на python, и мне сложно перебирать два списка списков. Мои два списка отформатированы как это:Итерация через два списка списков в python

L = [['cat', '1', '5'], ['cat', '7', '15'],['cat', '17', '20']] 
A = [['coordOne', '1', '3'],['coordTwo', '8', '9'],['coordThree', '11', '13'],['coordFour', '18', '21']] 

два чисел в каждом списке начальные и конечные координаты, и я хочу увидеть, если есть какое-либо перекрытие между началом и концом координат при сравнении двух списков, а затем сохранить информацию в новый список. Мой желаемый список после того, как программа работает выведет:

newList:[['cat', 'coordOne'],['cat', 'coordTwo', 'coordThree'], ['cat', 'coordFour']] 

мой код до сих пор

newList = [] 

    for i in range(len(L)): 
     for j in range (len(A)): 
      if i[1] >= j[1] and i[1] <= j[2] or i[2] >= j[1] and i[2] <= j[2] or i[1] <= j[1] and i[2] >= j[2] and j[2] >= i[2] or i[1] <= j[1] and i[2] >= j[2]: 
       newList.append(L[i][0], A[j][0]) 


    print (newList) 

Я получаю сообщение об ошибке, что «INT» объект не вызываемая.

+0

Да, я определенно имел в виду, i [1]> = j [1] и i [1] <= j [2] – Kevyn

+0

Что вы ожидаете от '' '' '' '' 'и' '' j''' ' быть? что возвращает '' 'range'''? Что происходит с '' 'для i в диапазоне (6): print i'''? – wwii

ответ

1

Ваши сравнения должны быть против Интс, обратите внимание '2' < '12' == False
Вы можете изменить сложное условие, чтобы проверить только граничные условия:

if int(i[1]) <= int(j[2]) and int(j[1]) <= int(i[2]): 

или

if max(int(i[1]), int(j[1])) <= min(int(i[2]), int(j[2])): 

Они должны быть достаточно чтобы определить, перекрываются ли диапазоны.

Я не предлагаю это, но это может быть сделано с пониманием, если вы принимаете немного другой выход:

>>> [(l, [a for a, a_start, a_end in A 
...  if int(l_start) <= int(a_end) and int(a_start) <= int(l_end)]) 
... for l, l_start, l_end in L] 
[('cat', ['coordOne']), 
('cat', ['coordTwo', 'coordThree']), 
('cat', ['coordFour'])] 

BTW ожидаемый выход для алгоритма ОП:

[['cat', 'coordOne'], ['cat', 'coordTwo'], ['cat', 'coordThree'], ['cat', 'coordFour']] 

Что вы могли бы сделать и с пониманием.

0

i и j являются int s. использование L[i][...] и A[j][...] в таком состоянии.

0
for i in range(len(L)): 
    for j in range (len(A)): 

i и j здесь оба типа int, если вы хотите, чтобы они были элементами L и A, использование:

for i in L: 
    for j in A: 

Соответственно, изменение:

newList.append(L[i][0], A[j][0]) 

к :

newList.append([i[0], j[0]]) 

Код запускается сейчас, однако результата не ожидается, что потребует дополнительной работы.

1

Я вам сделаю другую ошибку: IndexError: list index out of range. Это происходит из-за этот тест:

if [i][1] >= [j][1] 

[i] представляет собой список, содержащий только i, который затем пытается получить доступ к несуществующему индексу 1 из (он имеет только один элемент, который является индексом 0). У вас также есть вещи, которые только i[1] и j[1], которые сломаются с «int объект не подлежит расшифровке». Вы, кажется, имели в виду:

if L[i][j] >= A[j][1] 

Закрепление все это дает другую ошибку:

Traceback (most recent call last): 
    File "test.py", line 8, in <module> 
    newList.append(L[i][0], A[j][0]) 
TypeError: append() takes exactly one argument (2 given) 

Что вы можете исправить, добавив дополнительный набор скобок вокруг этого вызова (для добавления кортеж из L[i][0] и A[j][0]). Это дает тип продукции вы ожидаете:

[('cat', 'coordOne'), ('cat', 'coordThree'), ('cat', 'coordFour'), ('cat', 'coordOne'), ('cat', 'coordOne'), ('cat', 'coordFour')] 

Но есть лучший путь. Во-первых, итерация следующим образом:

for i in range(len(L)): 

почти всегда анти-шаблон.Вы только используете i и j для индексации двух списков; просто сделать:

for l in L: 

(но лучше выбирать имена переменных - это распространено иметь список с именем, как множественное число, как things и делать for thing in things:).

У вас есть две вложенные петли, чтобы рассмотреть каждый элемент L против каждого элемента A. Это называется декартово произведение и идиоматических способ сделать это состоит в использовании itertools:

import itertools as it 

for l, a in it.product(L, A): 
    if l[1] >= a[1] ... : 

Вы также можете рассмотреть возможность использования namedtuple, так что вы можете дать названия вещей в каждом списке, поэтому вы можете проверить такие вещи, как if l.start >= a.start:. Это значительно облегчит рассуждение о том, что именно делает ваш код, чтобы вы могли правильно оценить свое состояние.

2

Вы можете использовать функцию «zip».

L = [['cat', '1', '5'], ['cat', '7', '15'],['cat', '17', '20']] 
A = [['coordOne', '1', '3'],['coordTwo', '8', '9'],['coordThree', '11', '13'],['coordFour', '18', '21']] 
newList = [] 

for (i,j) in zip(L, A): 
    if i[1] >= j[1] and i[1] <= j[2] or i[2] >= j[1] and i[2] <= j[2] or i[1] <= j[1] and i[2] >= j[2] and j[2] >= i[2] or i[1] <= j[1] and i[2] >= j[2]: 
     newList.append((i[0], j[0])) 
+0

Это не сравнивает каждый элемент в L с каждым элементом в A, вы проверяете только L [0] с A [0] и L [1] с A [1] и т. Д. (A [4] никогда не сравнивается). – AChampion

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