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))
Em ruby:
ResponderEliminart = "p_dist m show_acs curses tget termcap"
Hash[*t.split]
ou
Hash[t.split.each_slice(2).to_a]