About me

About

2013-10-02

Pythonices, list -> map.

Como é que consigo facilmente converter o texto “p_dist m show_acs curses tget termcap” num dicionário chave-valor, ou seja, nisto: {'tget': 'termcap', 'p_dist': 'm', 'show_acs': 'curses'} ?

Uma simples iteração

Criar um dicionário vazio, iterar a lista dois a dois, fazer chave igual ao próximo.

t = "p_dist m show_acs curses tget termcap".split()

x = {}
for i in range(0, len(t), 2): x[t[i]] = t[i+1]
print x

Zip it

Substituir a iteração 2 a 2, por uma construção funcional – zip – que extrai dois elementos de cada vez da lista. Para isso a lista precisa de ser encapsulada num iterador, que funciona como um consumidor linear da lista.

t = "p_dist m show_acs curses tget termcap".split()

x = {}
it = iter(t)
for k,v in zip(it, it): x[k] = v
print x

Compactar o zip

  • [it,it] <=> [it]*2
  • f(it,it) <=> f(*[it]*2)

logo…

t = "p_dist m show_acs curses tget termcap".split()
x = {}
for k,v in zip(*[iter(t)]*2): x[k] = v
print x

Eliminar o loop explícito

  • zip(*[iter(t)]*2) = [('p_dist', 'm'), ('show_acs', 'curses'), ('tget', 'termcap')]

O lado direito é uma association list (alist), que é a representação python de um dicionário. Logo…

t = "p_dist m show_acs curses tget termcap".split()
x = dict(zip(*[iter(t)]*2))
print x

Verbatim

No limite podemos usar uma só expressão literal para criar um dicionário:

mymap = dict(zip(*[iter("""

chave1  valor1
chave2  valor2
chave3  valor3

""".split())]*2))

1 comentário:

  1. Em ruby:

    t = "p_dist m show_acs curses tget termcap"
    Hash[*t.split]

    ou

    Hash[t.split.each_slice(2).to_a]

    ResponderEliminar