I am looking for a simpler way to create this python dictionary. May I know if enumerate function can help?
a_dict = {'a':0, 'b':1, 'c':2, ....}
Using enumerate you can use a generator expression and string.ascii_lowercasewithin within dict :
>>> import string
>>> dict((j,i) for i,j in enumerate(string.ascii_lowercase))
{'a': 0, 'c': 2, 'b': 1, 'e': 4, 'd': 3, 'g': 6, 'f': 5, 'i': 8, 'h': 7, 'k': 10, 'j': 9, 'm': 12, 'l': 11, 'o': 14, 'n': 13, 'q': 16, 'p': 15, 's': 18, 'r': 17, 'u': 20, 't': 19, 'w': 22, 'v': 21, 'y': 24, 'x': 23, 'z': 25}
As enumerate returns tuples in format (index,element) you can loop over it and just change the indices with element then convert it to dict.
I would use an infinite number generator like itertools.count to generate numbers from 0. Then zip the ascii characters with count and create the tuples needed for the dictionary generation.
>>> from itertools import count, izip
>>> import string
>>>
>>> dict(izip(string.ascii_lowercase, count()))
{'a': 0, 'c': 2, 'b': 1, 'e': 4, 'd': 3, 'g': 6, 'f': 5, 'i': 8, 'h': 7, 'k': 10, 'j': 9, 'm': 12, 'l': 11, 'o': 14, 'n': 13, 'q': 16, 'p': 15, 's': 18, 'r': 17, 'u': 20, 't': 19, 'w': 22, 'v': 21, 'y': 24, 'x': 23, 'z': 25}
you may simply use string.ascii_lowercase which is string of all lowercase characters, then you zip the lowercase letters and list of number ranging from 0 to len(string.ascii_lowercase) and then convert them to dict.
However you may want to use some other set of alphabet as string.ascii_letters, string.ascii_uppercase , string.letters, string.punctuation, etc.
You can easily filter the keys that you want in your dictionary either by concatenating the above mentioned strings as string.ascii_lowercase+string.ascii_uppercase would give us a string containing first the 26 lowercase alphabets and then 26 uppercase alphabets, you may also apply slicing methods to get desired set of characters, like string.ascii_lowercase[0:15] would give you "abcdefghijklmn"
import string
alphabets = string.ascii_lowercase
print dict(zip(alphabets, range(len(alphabets))))
>>> {'a': 0, 'c': 2, 'b': 1, 'e': 4, 'd': 3, 'g': 6, 'f': 5, 'i': 8, 'h': 7, 'k': 10, 'j': 9, 'm': 12, 'l': 11, 'o': 14, 'n': 13, 'q': 16, 'p': 15, 's': 18, 'r': 17, 'u': 20, 't': 19, 'w': 22, 'v': 21, 'y': 24, 'x': 23, 'z': 25}
Assuming the .... means you want the alphabet:
{chr(i+97): i for i in range(26)}
Related
This question already has answers here:
creating dict where keys are alphabet letters and values are 1-26 using dict comprehension
(9 answers)
Closed 2 months ago.
i cant make a dict where to every one letter will be a value in the n + 1 format, start from 1.
this is my code:
dict1 = {x: y for x in 'abcdefghijklmnopqrstunvwxyz' for y in range(1, 20, 1)}
print(dict1)
i get it:
{'a': 19, 'b': 19, 'c': 19, 'd': 19, 'e': 19, 'f': 19, 'g': 19, 'h': 19, 'i': 19, 'j': 19, 'k': 19, 'l': 19, 'm': 19, 'n': 19, 'o': 19, 'p': 19, 'q': 19, 'r': 19, 's': 19, 't': 19, 'u': 19, 'v': 19, 'w': 19, 'y': 19, 'z': 19}
can u tell me why and how to get it: {'a': 1, 'b':2...
Use the tools provided by Python to make this easier to implement and read. First, don't hardcode the lowercase alphabet, use the stdlib string. Next, don't do the arithmetic yourself, it's easy to get wrong: there are 26 letters but range(1, 20, 1) generates only 19 digits. You also have a typo in your alphabet (I assume): tunvw. Lastly, use enumerate() which generates tuples consisting of an element of a sequence and an auto-incrementing integer, and use the start keyword argument to set the starting integer value.
import string
d = {x: y for x, y in enumerate(string.ascii_lowercase, start=1)}
Your code doesn't produce the result you want because for each integer from 1 to 19, it assigns the integer to the value for each key ('a', 'b', 'c', etc.). The first iteration of the outer for produces the dictionary {'a': 1, 'b': 2, 'c': 3, etc.}. Then, each subsequent iteration of the outer for overwrites these values with the new integer: 2, 3, 4, etc.
This is easy to see if we convert the comprehension to loops:
d = {}
for y in range(1, 20, 1):
for x in 'abcdefghijklmnopqrstuvwxyz':
d[x] = y
print(d)
{'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1, 'f': 1, 'g': 1, 'h': 1, 'i': 1, 'j': 1, 'k': 1, 'l': 1, 'm': 1, 'n': 1, 'o': 1, 'p': 1, 'q': 1, 'r': 1, 's': 1, 't': 1, 'u': 1, 'v': 1, 'w': 1, 'x': 1, 'y': 1, 'z': 1}
{'a': 2, 'b': 2, 'c': 2, 'd': 2, 'e': 2, 'f': 2, 'g': 2, 'h': 2, 'i': 2, 'j': 2, 'k': 2, 'l': 2, 'm': 2, 'n': 2, 'o': 2, 'p': 2, 'q': 2, 'r': 2, 's': 2, 't': 2, 'u': 2, 'v': 2, 'w': 2, 'x': 2, 'y': 2, 'z': 2}
{'a': 3, 'b': 3, 'c': 3, 'd': 3, 'e': 3, 'f': 3, 'g': 3, 'h': 3, 'i': 3, 'j': 3, 'k': 3, 'l': 3, 'm': 3, 'n': 3, 'o': 3, 'p': 3, 'q': 3, 'r': 3, 's': 3, 't': 3, 'u': 3, 'v': 3, 'w': 3, 'x': 3, 'y': 3, 'z': 3}
...
{'a': 19, 'b': 19, 'c': 19, 'd': 19, 'e': 19, 'f': 19, 'g': 19, 'h': 19, 'i': 19, 'j': 19, 'k': 19, 'l': 19, 'm': 19, 'n': 19, 'o': 19, 'p': 19, 'q': 19, 'r': 19, 's': 19, 't': 19, 'u': 19, 'v': 19, 'w': 19, 'x': 19, 'y': 19, 'z': 19}
edit: You don't need a comprehension to do this. There is another, pretty clean solution:
import string
d = dict(enumerate(string.ascii_lowercase, start=1))
This solution relies on the dict(iterable) constructor:
Help on class dict in module builtins:
class dict(object)
| dict() -> new empty dictionary
| dict(mapping) -> new dictionary initialized from a mapping object's
| (key, value) pairs
| dict(iterable) -> new dictionary initialized as if via:
| d = {}
| for k, v in iterable:
| d[k] = v
Try to zip the alphabet and the range to see what you get like that:
z1 = zip('abcdefghijklmnopqrstunvwxyz', range(1, 28, 1))
Which will give us:
for tup in z1:
print(tup)
Output:
('a', 1)
('b', 2)
('c', 3)
('d', 4)
('e', 5)
('f', 6)
('g', 7)
('h', 8)
('i', 9)
('j', 10)
('k', 11)
('l', 12)
('m', 13)
('n', 14)
('o', 15)
('p', 16)
('q', 17)
('r', 18)
('s', 19)
('t', 20)
('u', 21)
('n', 22)
('v', 23)
('w', 24)
('x', 25)
('y', 26)
('z', 27)
Now you can assign each element of each tuple to x, y:
d1 = {x, y for x, y in zip('abcdefghijklmnopqrstunvwxyz', range(1, 28, 1))}
Output:
print(d1)
{'a': 1,
'b': 2,
'c': 3,
'd': 4,
'e': 5,
'f': 6,
'g': 7,
'h': 8,
'i': 9,
'j': 10,
'k': 11,
'l': 12,
'm': 13,
'n': 22,
'o': 15,
'p': 16,
'q': 17,
'r': 18,
's': 19,
't': 20,
'u': 21,
'v': 23,
'w': 24,
'x': 25,
'y': 26,
'z': 27}
I am trying to create a caesar cipher, I created my own dictionary module and called in a for loop. The code is supposed to take an the i index of the input message and convert it to a number (via the dictionary module) add a cipher number input, convert it back to a new encrypted letter, and print it. The problem is that when I run it, I get an error message saying can't assign to operator. How can I fix this?
I have tried changing the i range, however I am afraid that it may be something with the module I made. I don't really understand the error message, so can you help me figure out the coding error?
This is my module code:
>>> import pprint, shelve, os, sys, shutil
>>> alphanum = {'a':1,'b':2,'c':3,'d':4,'e':5,'f':6,'g':7,'h':8,'i':9,'j':10,'k':11,'l':12,'m':13,'n':14,'o':15,'p':16,'q':17,'r':18,'s':19,'t':20,'u':21,'v':22,'w':23,'x':24,'y':25,'z':26}
>>> pprint.pformat(alphanum)
"{'a': 1,\n 'b': 2,\n 'c': 3,\n 'd': 4,\n 'e': 5,\n 'f': 6,\n 'g': 7,\n 'h': 8,\n 'i': 9,\n 'j': 10,\n 'k': 11,\n 'l': 12,\n 'm': 13,\n 'n': 14,\n 'o': 15,\n 'p': 16,\n 'q': 17,\n 'r': 18,\n 's': 19,\n 't': 20,\n 'u': 21,\n 'v': 22,\n 'w': 23,\n 'x': 24,\n 'y': 25,\n 'z': 26}"
>>> AlphaCaesar = open('Caesar.py','w')
>>> AlphaCaesar.write('alphanum = {} \n'.format(pprint.pformat(alphanum)))
263
>>> AlphaCaesar.close()
>>> import Caesar
>>> Caesar.alphanum
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8, 'i': 9, 'j': 10, 'k': 11, 'l': 12, 'm': 13, 'n': 14, 'o': 15, 'p': 16, 'q': 17, 'r': 18, 's': 19, 't': 20, 'u': 21, 'v': 22, 'w': 23, 'x': 24, 'y': 25, 'z': 26}
and this is my caesar cipher program code:
import Caesar
alphavalues = Caesar.alphanum
print('enter your message to encrypt')
message = input()
print('enter the cipher number')
ciphernum = input()
for i in range(0,len[encryption]):
alphavalues[message[i]] + int(ciphernum) = newcaesaralpha
print(alphavalues[newcaesaralpha])
You have the assignment backwards. newcaesaralpha is the target, and must appear on the left. In addition, you need to use % to ensure the sum is between 1 and 26.
newcaesaralpha = (alphavalues[message[i]] - 1 + int(ciphernum)) % 26 + 1
(The algorithm is simpler if you number the alphabet 0 to 25 instead of 1 to 26.)
I have something like this in Python to count the frequency of characters in a text, but i can't sort the values on the dictionary "v".
abcedario='abcdefghijklmnopqrstvuxwyz'
v = {}
count = 0
for c in abcedario:
count = 0
for char in text:
if c == char:
count = count +1
v[c] = count
sorted(v.items(), key=lambda x:x[1])
print v
I try to search here on stackoverflow but never solve my problem, the aspect of the output is this:
{'a': 2, 'b': 4, 'e': 4, 'd': 36, 'g': 31, 'f': 37, 'i': 14, 'h': 4, 'k': 51, 'j': 31, 'l': 34, 'n': 18, 'q': 13, 'p': 2, 'r': 9, 'u': 1, 't': 1, 'w': 36, 'v': 15, 'y': 14, 'x': 8, 'z': 10}
I want sort by value, so it's different from other posts.
If you just want to print them in order, just print the output of sorted:
abcedario='abcdefghijklmnopqrstvuxwyz'
v = {}
count = 0
for c in abcedario:
count = 0
for char in text:
if c == char:
count = count +1
v[c] = count
print sorted(v.items(), key=lambda x:x[1])
For text = "helloworld" you get:
[('e', 1), ('d', 1), ('h', 1), ('r', 1), ('w', 1), ('o', 2), ('l', 3)]
A python dictionary is an unordered collection of items. Therefore, it can't be sorted.
Try looking into OrderedDict from collections.
you can use Counter
from collections import Counter
text = "I have something like this in Python to count the frequency of characters in a text, but i can't sort the values on the dictionary"
print(Counter(text))
output:
Counter({' ': 24, 't': 15, 'e': 11, 'n': 9, 'h': 8, 'i': 8, 'o': 8, 'a': 7, 'c': 6, 's': 5, 'r': 5, 'u': 4, 'y': 3, 'f': 2, 'l': 2, 'v': 2, "'": 1, 'q': 1, 'd': 1, 'I': 1, 'm': 1, 'g': 1, 'b': 1, 'x': 1, ',': 1, 'P': 1, 'k': 1})
I am trying to create a python dictionary with the following values in python 2.7.3:
'A':1
'B':2
'C':3
.
.
.
.
'Z':26
using either of the following lines:
theDict = {x:y for x in map(chr,range(65,91)) for y in range(1,27)}
or
theDict = {x:y for x in map(chr,range(65,91)) for y in list(range(1,27))}
In both cases, I get the following result:
'A':26
'B':26
'C':26
.
.
.
.
'Z':26
I don't understand why the second for is not generating the numbers 1-26. Maybe it is, but if so, I don't understand why I am only getting 26 for the value of each key. If I don't create a dictionary (i.e. change x:y with just x or y), x = capital letters and y = 1-26.
Can someone explain what I am doing wrong and suggest a possible approach to get the result that I want.
Why it's wrong: Your list comprehension is nested. It's effectively something like this:
d = {}
for x in map(chr, range(65, 91)):
for y in range(1,27):
d[x] = y
As you can see, this isn't what you want. What it does is set y to 1, then walk through the alphabet, setting all letters to 1 i.e. {'A':1, 'B':1, 'C':1, ...}. Then it does it again for 2,3,4, all the way to 26. Since it's a dict, later settings overwrite earlier settings, and you see your result.
There are several options here, but in general, the solution to iterate over multiple companion lists is a pattern more like this:
[some_expr(a,b,c) for a,b,c in zip((a,list,of,values), (b, list, of, values), (c, list, of values))]
The zip pulls one value from each of the sublists and makes it into a tuple for each iteration. In other words, it converts 3 lists of 4 items each, into 4 lists of 3 items each (in the above). In your example, you have 2 lists of 26 items, when you want 26 pairs; zip will do that for you.
Try:
>>> {chr(k):k-64 for k in range(65,91)}
{'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}
Or, if you want to do what you are doing use zip:
>>> {x:y for x,y in zip(map(chr,range(65,91)),range(1,27))}
{'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}
The reason yours is not working, is that your comprehension is executing the inner the outer loop times. ie, try this in the shell:
>>> [(chr(outter), inner) for outter in range(65,91) for inner in range(1,27)]
[('A', 1), ('A', 2), ('A', 3), ('A', 4),... ('A', 26),
...
...
('Z', 1), ('Z', 2), ('Z', 3), ('Z', 4), ..., ('Z', 26)]
So if you do:
>>> len([(chr(outter), inner) for outter in range(65,91) for inner in range(1,27)])
676
You can see that it is executing 26x26 times (26x26=676)
Since a dict will just update with the new value, the last value for each letter is used:
>>> dict([(chr(outter), inner) for outter in range(65,91) for inner in range(1,27)])
{'A': 26, 'C': 26, 'B': 26, 'E': 26, 'D': 26, 'G': 26, 'F': 26, 'I': 26, 'H': 26, 'K': 26, 'J': 26, 'M': 26, 'L': 26, 'O': 26, 'N': 26, 'Q': 26, 'P': 26, 'S': 26, 'R': 26, 'U': 26, 'T': 26, 'W': 26, 'V': 26, 'Y': 26, 'X': 26, 'Z': 26}
Which shows why you are getting what you are getting.
You can try the following:
theDict = {chr(y):y - 64 for y in range(65, 91)}
print theDict
Output:
{'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}
I'm looking of creating a dictionary in python
which its keys are the chars '0' to '9' , afterwards keys from 'a' to 'z',
and their ids should be a counter from 0 to 36
like this:
dict = {'0':0, '1':1, '2':2, ....., '9':9, 'a':10, .... , 'x':33, 'y':34, 'z':35}
I manage to write this
dict = {}
for i in range(10):
dict[str(i)] = i
ord_a = ord('a')
for i in range(0,26):
dict[chr(ord_a + i)] = i+10
Can you help me with a better way to implement it?
And one more thing, print(dict) returns an unsorted object:
{'d': 13, 'e': 14, 'f': 15, 'g': 16, 'r': 27, 'a': 10, 'b': 11,
'c': 12, 'l': 21, 'm': 22, 'n': 23, 'o': 24, 'h': 17, 'i': 18,
'j': 19, 'k': 20, '4': 4, '5': 5, '6': 6, '7': 7, '0': 0, '1': 1,
'2': 2, '3': 3, '8': 8, '9': 9, 'z': 35, 't': 29, 'u': 30,
'x': 33, 'v': 31, 'y': 34, 'w': 32, 's': 28, 'p': 25, 'q': 26}
Why's that? I actually initialize it quite sorted, no?
import string
keys = string.digits+string.ascii_lowercase
values = range(len(keys))
d = dict(zip(keys,values))
dicts have unordered keys. To have ordered keys, use a collections.OrderedDict. (Also, never name a variable dict or list, etc., since this prevents you from easily accessing the Python built-in of the same name. The built-in is useful, as you can see above.)