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
  • 159,742
  • 34
  • 281
  • 339
Alcott
  • 17,905
  • 32
  • 116
  • 173

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
  • 15,415
  • 15
  • 80
  • 144
  • 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
  • 52,533
  • 16
  • 102
  • 136
  • 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
  • 94,853
  • 25
  • 187
  • 187
2

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
  • 159,742
  • 34
  • 281
  • 339
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,138
  • 7
  • 13
1

another one liner:

dict([(k,s.index(k)) for (k,v) in d.items()])
DhruvPathak
  • 42,059
  • 16
  • 116
  • 175
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
  • 27,895
  • 4
  • 34
  • 52
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
  • 10,378
  • 7
  • 39
  • 55
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
  • 19,457
  • 10
  • 47
  • 56