python с именем Кортеж в словарь


У меня есть именованный кортеж класса в python

class Town(collections.namedtuple('Town', [
    'name', 
    'population',
    'coordinates',
    'population', 
    'capital', 
    'state_bird'])):
    # ...

то, что я хотел бы сделать, это превратить это в словарь. Я признаю, что python не является одним из моих сильных языков. Ключ в том, что я не хочу, чтобы он был жестко привязан к имени или номерам полей, которые у меня есть.

есть ли способ написать его так, чтобы я мог добавить больше полей или передать совершенно другой именованный кортеж и получить словарь.

Edit: я не могу изменить исходное определение класса его в чей-то elses код. Поэтому мне нужно взять пример города и преобразовать его в словарь.

4 81

4 ответа:

TL; DR: есть метод _asdict предусмотренные для этого.

вот демонстрация использования:

>>> fields = ['name', 'population', 'coordinates', 'capital', 'state_bird']
>>> Town = collections.namedtuple('Town', fields)
>>> funkytown = Town('funky', 300, 'somewhere', 'lipps', 'chicken')
>>> funkytown._asdict()
OrderedDict([('name', 'funky'),
             ('population', 300),
             ('coordinates', 'somewhere'),
             ('capital', 'lipps'),
             ('state_bird', 'chicken')])

это документированный способ namedtuples, т. е. В отличие от обычного соглашения в python ведущий подчеркивание на имя метода не существует, чтобы препятствовать использованию. Наряду с другими методами, добавленными в namedtuples,_make,_replace,_source,_fields, он имеет подчеркивание только для того, чтобы попытаться предотвратить конфликты с возможными именами полей.


Примечание: для некоторых 2.7.5

>>> vars(funkytown)
OrderedDict([('name', 'funky'),
             ('population', 300),
             ('coordinates', 'somewhere'),
             ('capital', 'lipps'),
             ('state_bird', 'chicken')])

некоторое время в документации упоминалось, что _asdict устарел (см. здесь), и предложил использовать встроенный метод ВАР. Этот совет теперь устарел; чтобы исправить ошибка, связанные с наследованием, в __dict__ имущества, присутствовал на namedtuples снова был удален этот коммит.

есть встроенный метод на namedtuple случаях для этого _asdict.

как уже обсуждалось в комментариях, на некоторых версиях vars() также будет делать это, но это, по-видимому, сильно зависит от деталей сборки, тогда как _asdict должна быть надежной. В некоторых версиях _asdict был отмечен как устаревший, но комментарии указывают, что это уже не так, как в 3.4.

на Ubuntu 14.04 LTS версии python2.7 и python3. 4 The __dict__ свойство работало как ожидалось. Элемент _asdictметод также работал, но я склонен использовать стандартный, единообразный api свойств вместо локализованного неоднородного api.

$ вместо python2.7

# Works on:
# Python 2.7.6 (default, Jun 22 2015, 17:58:13)  [GCC 4.8.2] on linux2
# Python 3.4.3 (default, Oct 14 2015, 20:28:29)  [GCC 4.8.4] on linux

import collections

Color = collections.namedtuple('Color', ['r', 'g', 'b'])
red = Color(r=256, g=0, b=0)

# Access the namedtuple as a dict
print(red.__dict__['r'])  # 256

# Drop the namedtuple only keeping the dict
red = red.__dict__
print(red['r'])  #256

видя, как дикт это семантический способ получить словарь, представляющий soemthing, (по крайней мере, насколько мне известно).


Это неплохо бы накопить таблицу основных версий и платформ python и их поддержку для __dict__, в настоящее время у меня есть только одна версия платформы и две версии python, как указано выше.

| Platform         | PyVer     | __dict__ | _asdict |
| -------------    | --------- | -------- | ------- |
| Ubuntu 14.04 LTS | Python2.7 | yes      | yes     |
| Ubuntu 14.04 LTS | Python3.4 | yes      | yes     |

Python 3. Выделите любое поле в словарь в качестве необходимого индекса для словаря, я использовал "имя".

import collections

Town = collections.namedtuple("Town", "name population coordinates capital state_bird")

town_list = []

town_list.append(Town('Town 1', '10', '10.10', 'Capital 1', 'Turkey'))
town_list.append(Town('Town 2', '11', '11.11', 'Capital 2', 'Duck'))

town_dictionary = {t.name: t for t in town_list}