Атрибут можно обновить только один раз во вложенном цикле for - PullRequest
0 голосов
/ 11 июля 2020

Я новичок в Python и у меня проблемы с моим первым скриптом Python. У меня есть список данных с атрибутом .tag, который изначально установлен на 0.

lst = [a, b, c, d, e, f]
for x in lst:
    x.tag = 0

Затем я получил результаты для реальных тегов и соответствующих индексов элементов списка. Он хранится в списке словарей. Очевидно, что некоторые элементы в списке имеют несколько тегов. Теперь я хочу обновить теги для всех элементов в списке, чтобы каждый элемент имел атрибут тега, например, f.tag = [2,3,4,5]. Я написал следующий сценарий. Идея состоит в том, чтобы пройти l oop через каждый словарь и получить индексы и тег. Затем выполните l oop по каждому индексу и проверьте, имеет ли соответствующий элемент списка тег = 0. Если да, измените 0 на новый тег как единый список элементов; если нет, это означает, что он был обновлен ранее, поэтому просто добавьте новый тег. Мой сценарий ниже:

results = [{'indices':(2), 'tag':0}, {'indices':(1,3), 'tag':1}, {'indices':(0,3,4,5), 'tag':2}, {'indices':(4,5), 'tag':3}, {'indices':(1,5), 'tag':4}, {'indices':(5), 'tag':5}]

for dct in results:
    indices = dct['indices']
    t = dct['tag']
    for i in indices:
        if lst[i].tag == 0:
            lst[i].tag = [t]
        elif t not in lst[i].tag:
            print('The code ever goes here')
            lst[i].tag.append(t) 

Однако после того, как я его запустил, я никогда не вижу, чтобы распечатывалась надпись «Код когда-либо здесь». Затем я проверяю список, я вижу, что все элементы с ненулевым реальным тегом обновляются, но только один раз. Это означает, что тег элементов нельзя обновить второй раз. Это определенно не нормально, поскольку есть элементы, которые имеют несколько тегов и требуют постоянного обновления. Я понятия не имею, что могло пойти не так в моем коде.

Ответы [ 2 ]

0 голосов
/ 11 июля 2020

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

In [38]: class thing(): 
    ...:     def __init__(self): 
    ...:         self.tags = [0,]   # the default 
    ...:          
    ...:          
    ...:                                                                        

In [39]: # make some "things"                                                   

In [40]: x = thing()                                                            

In [41]: y = thing()                                                            

In [42]: z = thing()                                                            

In [43]: x.tags                                                                 
Out[43]: [0]

In [44]: x.tags.append(44)                                                      

In [45]: x.tags.append(-2)                                                      

In [46]: z.tags.append(3)                                                       

In [47]: for t in [x, y, z]: 
    ...:     print(t.tags) 
    ...:                                                                        
[0, 44, -2]
[0]
[0, 3]
0 голосов
/ 11 июля 2020

Лог c довольно запутан, но я думаю, что делает то, что вы хотите. Я подозреваю, что проблема в вашем вводе results. В частности:

  • Для одноэлементных индексов, таких как (2), измените их на (2,), чтобы их можно было правильно итерировать. (2) просто вычисляется как 2 и не может быть повторен.
  • Последний элемент должен быть {'indices':(5,), 'tag':5} вместо {'5':, 'tag':5}.

После их изменения я могу запустите минимальный рабочий пример:

class A:
    def __init__(self):
        self.tag = 0

lst = [A() for _ in range(6)]
results = [
    {"indices": (2,), "tag": 0},
    {"indices": (1, 3), "tag": 1},
    {"indices": (0, 3, 4, 5), "tag": 2},
    {"indices": (4, 5), "tag": 3},
    {"indices": (1, 5), "tag": 4},
    {"indices": (5,), "tag": 5},
]

for dct in results:
    indices = dct["indices"]
    t = dct["tag"]
    for i in indices:
        if lst[i].tag == 0:
            lst[i].tag = [t]
        elif t not in lst[i].tag:
            print("The code does go here")
            lst[i].tag.append(t)

, за которым следует

for x in lst:
  print(x.tag)
>
[2]
[1, 4]
[0]
[1, 2]
[2, 3]
[2, 3, 4, 5]
...