Crie um dicionário com compreensão de lista


1280

Eu gosto da sintaxe de compreensão da lista Python.

Também pode ser usado para criar dicionários? Por exemplo, iterando sobre pares de chaves e valores:

mydict = {(k,v) for (k,v) in blah blah blah}  # doesn't work

Relacionado: collections.Counteré um tipo especializado de ditado para contar coisas: Usando um dicionário para contar os itens de uma lista
smci

Respostas:


1898

Do Python 2.7 e 3 em diante, você deve apenas usar a sintaxe de compreensão do dict :

{key: value for (key, value) in iterable}

No Python 2.6 e versões anteriores, o dictbuilt-in pode receber uma iterável de pares de chave / valor, para que você possa transmitir uma compreensão de lista ou expressão de gerador. Por exemplo:

dict((key, func(key)) for key in keys)

No entanto, se você já possui iterável (s) de chaves e / ou vals, não precisa usar nenhuma compreensão - é mais simples ligar dictdiretamente para o built-in:

# consumed from any iterable yielding pairs of keys/vals
dict(pairs)

# "zipped" from two separate iterables of keys/vals
dict(zip(list_of_keys, list_of_values))

1
e se eu tiver um caso de lista de palavras ['gato', 'cachorro', 'gato'] e quiser fazer um ditado com chave como palavra e valor como contagem? Existe uma sintaxe curta e eficiente para isso?
18719 cryanbhu

@cryanbhu Se o que você quer dizer é contar as repetições de um determinado elemento da lista, há uma classe Counter no pacote de coleções: docs.python.org/2/library/collections.html#collections.Counter
fortran

237

No Python 3 e Python 2.7+, as compreensões de dicionário se parecem com as abaixo:

d = {k:v for k, v in iterable}

Para Python 2.6 ou anterior, consulte a resposta do fortran .


57

Na verdade, você nem precisa iterar sobre o iterável se ele já compreender algum tipo de mapeamento, o construtor de ditado fazendo isso graciosamente por você:

>>> ts = [(1, 2), (3, 4), (5, 6)]
>>> dict(ts)
{1: 2, 3: 4, 5: 6}
>>> gen = ((i, i+1) for i in range(1, 6, 2))
>>> gen
<generator object <genexpr> at 0xb7201c5c>
>>> dict(gen)
{1: 2, 3: 4, 5: 6}


32

Crie um dicionário com compreensão de lista em Python

Eu gosto da sintaxe de compreensão da lista Python.

Também pode ser usado para criar dicionários? Por exemplo, iterando sobre pares de chaves e valores:

mydict = {(k,v) for (k,v) in blah blah blah}

Você está procurando a frase "compreensão de ditados" - na verdade:

mydict = {k: v for k, v in iterable}

Supondo que blah blah blahé uma iterável de duas tuplas - você está tão perto. Vamos criar alguns "blahs" assim:

blahs = [('blah0', 'blah'), ('blah1', 'blah'), ('blah2', 'blah'), ('blah3', 'blah')]

Sintaxe de compreensão de ditado:

Agora a sintaxe aqui é a parte do mapeamento. O que torna isso uma dictcompreensão em vez de uma setcompreensão (que é o que o seu pseudo-código se aproxima) é o cólon, :como abaixo:

mydict = {k: v for k, v in blahs}

E vemos que funcionou e deve manter a ordem de inserção como no Python 3.7:

>>> mydict
{'blah0': 'blah', 'blah1': 'blah', 'blah2': 'blah', 'blah3': 'blah'}

No Python 2 e até 3.6, o pedido não era garantido:

>>> mydict
{'blah0': 'blah', 'blah1': 'blah', 'blah3': 'blah', 'blah2': 'blah'}

Adicionando um filtro:

Todas as compreensões apresentam um componente de mapeamento e um componente de filtragem que você pode fornecer com expressões arbitrárias.

Então você pode adicionar uma parte do filtro ao final:

>>> mydict = {k: v for k, v in blahs if not int(k[-1]) % 2}
>>> mydict
{'blah0': 'blah', 'blah2': 'blah'}

Aqui estamos apenas testando se o último caractere é divisível por 2 para filtrar os dados antes de mapear as chaves e os valores.


23

Versão Python <2.7 (RIP, 3 de julho de 2010 a 31 de dezembro de 2019) , faça o seguinte:

d = dict((i,True) for i in [1,2,3])

Versão Python> = 2.7, faça o seguinte:

d = {i: True for i in [1,2,3]}

22

Para adicionar à resposta do @ fortran, se você quiser repetir uma lista de chaves key_liste uma lista de valores value_list:

d = dict((key, value) for (key, value) in zip(key_list, value_list))

ou

d = {(key, value) for (key, value) in zip(key_list, value_list)}

6

Aqui está outro exemplo de criação de dicionário usando compreensão de ditado:

O que estou tentando fazer aqui é criar um dicionário do alfabeto em que cada par; é a letra em inglês e sua posição correspondente no alfabeto inglês

>>> import string
>>> dict1 = {value: (int(key) + 1) for key, value in 
enumerate(list(string.ascii_lowercase))}
>>> dict1
{'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4, 'g': 7, 'f': 6, 'i': 9, 'h': 8, 
'k': 11, 'j': 10, 'm': 13, 'l': 12, 'o': 15, 'n': 14, 'q': 17, 'p': 16, 's': 
19, 'r': 18, 'u': 21, 't': 20, 'w': 23, 'v': 22, 'y': 25, 'x': 24, 'z': 26}
>>> 

Observe o uso de enumerar aqui para obter uma lista de alfabetos e seus índices na lista e trocar os alfabetos e índices para gerar o par de valores-chave para o dicionário

Espero que ele lhe dê uma boa idéia do dicionário e incentive você a usá-lo com mais frequência para tornar seu código compacto


1
Resposta Nice - simplificado:d = {k: v+1 for v, k in enumerate(string.ascii_lowercase)}
johnnydrama

4

Tente isso,

def get_dic_from_two_lists(keys, values):
    return { keys[i] : values[i] for i in range(len(keys)) }

Suponha que temos duas listas país e capital

country = ['India', 'Pakistan', 'China']
capital = ['New Delhi', 'Islamabad', 'Beijing']

Em seguida, crie um dicionário a partir das duas listas:

print get_dic_from_two_lists(country, capital)

A saída é assim,

{'Pakistan': 'Islamabad', 'China': 'Beijing', 'India': 'New Delhi'}

9
você poderia ter usado zip
Andre Simon

2
>>> {k: v**3 for (k, v) in zip(string.ascii_lowercase, range(26))}

O Python suporta compreensões de ditado, que permitem expressar a criação de dicionários em tempo de execução usando uma sintaxe concisa da mesma forma.

Uma compreensão de dicionário assume o formato {key: value for (key, value) em iterável}. Essa sintaxe foi introduzida no Python 3 e suportada até o Python 2.7, portanto, você poderá usá-lo independentemente da versão do Python que instalou.

Um exemplo canônico é pegar duas listas e criar um dicionário em que o item em cada posição na primeira lista se torna uma chave e o item na posição correspondente na segunda lista se torna o valor.

A função zip usada dentro dessa compreensão retorna um iterador de tuplas, em que cada elemento na tupla é obtido da mesma posição em cada uma das iteráveis ​​de entrada. No exemplo acima, o iterador retornado contém as tuplas ("a", 1), ("b", 2) etc.

Resultado:

('i': 512, 'e': 64, 'o': 2744, 'h': 343, 'l': 1331, 's': 5832, 'b': 1, 'w': 10648, ' c ': 8,' x ': 12167,' y ': 13824,' t ': 6859,' p ': 3375,' d ': 27,' j ': 729,' a ': 0,' z ' : 15625, 'f': 125, 'q': 4096, 'u': 8000, 'n': 2197, 'm': 1728, 'r': 4913, 'k': 1000, 'g': 216 , 'v': 9261}


2

Este código criará um dicionário usando compreensão de lista para várias listas com valores diferentes que podem ser usados ​​para pd.DataFrame()

#Multiple lists 
model=['A', 'B', 'C', 'D']
launched=[1983,1984,1984,1984]
discontinued=[1986, 1985, 1984, 1986]

#Dictionary with list comprehension
keys=['model','launched','discontinued']
vals=[model, launched,discontinued]
data = {key:vals[n] for n, key in enumerate(keys)}

enumeratepassará npara valspara combinar cada um keycom sua lista


1

Apenas para dar outro exemplo. Imagine que você tem a seguinte lista:

nums = [4,2,2,1,3]

e você deseja transformá-lo em um ditado em que a chave é o índice e o valor é o elemento na lista. Você pode fazer isso com a seguinte linha de código:

{index:nums[index] for index in range(0,len(nums))}

0

Você pode criar um novo ditado para cada par e mesclá-lo com o ditado anterior:

reduce(lambda p, q: {**p, **{q[0]: q[1]}}, bla bla bla, {})

Obviamente, isso se aproxima exige reducea partir functools.


mesma idéia: reduzir (lambda p, q: {** p, ** dict ([q])}, bla bla bla, {})
Mahmoud Khaled
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.