Довольно часто, когда я создаю файл XML из данных, хранящихся в классе, я часто получал ошибки, если атрибут не существовал или имел тип None
. В этом случае моя проблема не зная, что такое имя атрибута, как указано в вашем вопросе, а скорее данные, хранящиеся в этом атрибуте.
class Pet:
def __init__(self):
self.hair = None
self.color = None
Если я использовал hasattr
для сделайте это, он вернет True
, даже если значение атрибута имеет тип None
, и это приведет к ошибке моей команды ElementTree set
.
hasattr(temp, 'hair')
>>True
Если значение атрибута имело тип None
, getattr
также вернет его, что приведет к сбою моей команды ElementTree set
.
c = getattr(temp, 'hair')
type(c)
>> NoneType
Теперь я использую следующий метод, чтобы позаботиться об этих случаях:
def getRealAttr(class_obj, class_attr, default = ''):
temp = getattr(class_obj, class_attr, default)
if temp is None:
temp = default
elif type(temp) != str:
temp = str(temp)
return temp
Это когда и как я использую getattr
.
Вы можете инициализировать словарь со счетчиками:
liste = ['a','b','a','a','b']
compte = {}
result = []
for valeur in liste:
compte[valeur] = compte.get(valeur, 0) + 1
result.append((valeur, compte[valeur]))
print(result)
Вы можете использовать Counter
из модуля collections
:
from collections import Counter
liste = ['a','b','a','a','b']
def counter(iterable):
c = Counter()
for i in iterable:
c.update(i)
yield i, c[i]
print(list(counter(liste)))
Выходы:
[('a', 1), ('b', 1), ('a', 2), ('a', 3), ('b', 2)]
Используйте функцию генератора.
from collections import defaultdict
def with_running_count(values):
counts = defaultdict(int)
for value in values:
counts[value] += 1
yield value, counts[value]
>>> print(*with_running_count('abaab'))
('a', 1) ('b', 1) ('a', 2) ('a', 3) ('b', 2)
Одно из преимуществ использования генератора над другими предложениями состоит в том, что генераторы ленивы. Это означает, что вы можете передавать итераторы, которые возвращают бесконечный (или очень большой) поток данных, поскольку генератор потребляет только входной поток по мере необходимости.
# an endless iterator
coin = iter(lambda: random.choice(['heads', 'tails']), None)
# the running count will also be endless
toss = with_running_count(coin)
>>> next(toss), next(toss), next(toss)
(('tails', 1), ('tails', 2), ('heads', 1))
Ваш ожидаемый результат - это список, а не словарь. Исправить ваш код будет использование вашего dict для подсчета, но добавление к списку:
>>> liste = ['a','b','a','a','b']
>>>
>>> compte = dict.fromkeys(liste,0) #Or use a default dict
>>> result = []
>>> for valeur in liste:
... compte[valeur] += 1
... result.append((valeur,compte[valeur]))
...
>>> print(result)
[('a', 1), ('b', 1), ('a', 2), ('a', 3), ('b', 2)]
Вы можете просто изменить свой код следующим образом:
liste = ['a','b','a','a','b']
liste2 = []
compte = {}.fromkeys(set(liste),0)
for valeur in liste:
compte[valeur] += 1
liste2.append(valeur + ':' + str(compte[valeur]))
print(liste2)
Важно сказать: то, что вы пытаетесь сделать, это не кортеж, а список, потому что он изменен. Ваша переменная compte
является dictionary
.