6

Code goes below:

d = {'a':0, 'b':0, 'c':0, 'd':0}  #at the beginning, all the values are 0.
s = 'cbad'  #a string
indices = map(s.index, d.keys())  #get every key's index in s, i.e., a-2, b-1, c-0, d-3
#then set the values to keys' index
d = dict(zip(d.keys(), indices))  #this is how I do it, any better way?
print d  #{'a':2, 'c':0, 'b':1, 'd':3}

Any other way to do that?

PS. the code above is just a simple one to demonstrate my question.

jpp
  • 147,904
  • 31
  • 244
  • 302
Alcott
  • 16,879
  • 27
  • 109
  • 172

9 Answers9

10

Something like this might make your code more readable:

dict([(x,y) for y,x in enumerate('cbad')])

But you should give more details what you really want to do. Your code will probably fail if the characters in s do not fit the keys of d. So d is just a container for the keys and the values are not important. Why not start with a list in that case?

Achim
  • 14,927
  • 14
  • 75
  • 135
  • ya, absolutely I know that. I can guarantee that the chars in s fit the keys of d. Thanks for your enumerate way, I happened to forget it. – Alcott Aug 18 '11 at 08:41
  • 2
    Nice. Also you can omit the brackets. – Owen Aug 18 '11 at 08:54
3

What about

d = {'a':0, 'b':0, 'c':0, 'd':0}
s = 'cbad'
for k in d.iterkeys():
    d[k] = s.index(k)

? It's no functional programming anymore but should be more performant and more pythonic, perhaps :-).

EDIT: A function variant using python dict-comprehensions (needs Python 2.7+ or 3+):

d.update({k : s.index(k) for k in d.iterkeys()})

or even

{k : s.index(k) for k in d.iterkeys()}

if a new dict is okay!

Johannes Weiss
  • 50,352
  • 15
  • 99
  • 134
  • For Python 3+ `iterkeys()` has been replaced with `keys()`, see [this question](https://stackoverflow.com/questions/30418481/error-dict-object-has-no-attribute-iteritems) – Adriaan Apr 10 '20 at 08:21
3

use update() method of dict:

d.update((k,s.index(k)) for k in d.iterkeys())
HYRY
  • 89,863
  • 23
  • 181
  • 185
1

You don't need to pass a list of tuples to dict. Instead, you can use a dictionary comprehension with enumerate:

s = 'cbad'
d = {v: k for k, v in enumerate(s)}

If you need to process the intermediary steps, including initial setting of values, you can use:

d = dict.fromkeys('abcd', 0)
s = 'cbad'

indices = {v: k for k, v in enumerate(s)}

d = {k: indices[k] for k in d}         # dictionary comprehension
d = dict(zip(d, map(indices.get, d)))  # dict + zip alternative

print(d)

# {'a': 2, 'b': 1, 'c': 0, 'd': 3}
jpp
  • 147,904
  • 31
  • 244
  • 302
1
for k in d.iterkeys():
    d[k] = s.index[k]

Or, if you don't already know the letters in the string:

d = {}
for i in range(len(s)):
    d[s[i]]=i
Patrick
  • 1,128
  • 7
  • 13
1

another one liner:

dict([(k,s.index(k)) for (k,v) in d.items()])
DhruvPathak
  • 40,405
  • 15
  • 109
  • 170
0

You choose the right way but think that no need to create dict and then modify it if you have ability to do this in the same time:

keys = ['a','b','c','d']
strK = 'bcad'
res = dict(zip(keys, (strK.index(i) for i in keys)))
Artsiom Rudzenka
  • 26,491
  • 4
  • 32
  • 51
0

Dict comprehension for python 2.7 and above

{key : indice for key, indice in zip(d.keys(), map(s.index, d.keys()))}
Simon Bergot
  • 9,930
  • 7
  • 37
  • 54
0
>>> d = {'a':0, 'b':0, 'c':0, 'd':0}
>>> s = 'cbad'
>>> for x in d:  
        d[x]=s.find(x)
>>> d
    {'a': 2, 'c': 0, 'b': 1, 'd': 3}
Kracekumar
  • 18,069
  • 10
  • 44
  • 53