Raëgan
Raëgan

Reputation: 17

Python: Dictionary and lists

I want a dictionary with 26 keys without value (one for each letter), that will read a string and create a list which will contain the positions of the letter in the string, and associate it with the key.

Example: If I have the following string AZERTYUIOPAAAZ, the key A in the dictionary must have as a value the list [0,10,11,12], cause we find the letter A at these positions in the string. I managed to make my dictionary take one position for each letter, but I cannot create a list with ALL the positions.

Here's my code:

string1 = "SQUALALANOUSSOMESPARTISETJETEDTESTE"
taille = len(string1)
dictio = dict()
dictio = {'A':None,'B':None,'C':None,'D':None,'E':None,'F':None,'G':None,'H':None,'I':None,'J':None,'K':None,'L':None,'M':None,'N':None,'O':None,'P':None,'Q':None,'R':None,'S':None,'T':None,'U':None,'V':None,'W':None,'X':None,'Y':None,'Z':None}
a = 0
for a in range(taille):
    dictio[string1[a]] = a
    print(dictio)

Upvotes: 1

Views: 117

Answers (5)

MutantOctopus
MutantOctopus

Reputation: 3581

As L-Jones explained, your original system fails because you're setting the values of the dictionary at each point. To explain, if you do the following:

a = 1
a = 2

a will have the value of 2 and no record of having the value of 1. This is effectively the same as replacing the values of a dictionary at a given key.

If you initialize the default values of the dictionary to an empty list, [], instead of None, you can use append to add indices wherever necessary. See the following:

import string
string1 = "SQUALALANOUSSOMESPARTISETJETEDTESTE"
taille = len(string1)
dictio = dict()
dictio = {letter: [] for letter in string.ascii_uppercase}
# The above is a shorter alternative to typing out all of the letter-empty list pairs by hand
# a = 0 is unnecessary because a will be initialized to 0 with the range
for a in range(taille):
    dictio[string1[a]].append(a)
print(dictio)

Note that the dictionary won't be sorted A-Z, for reasons I'm not wholly sure about, but it will contain everything you need.

If you don't care about letters with no indices, however, see Nander Speerstra's proposed solution in his answer: The variable dict, which will not include a key that's not in the string. It will reduce memory cost at the expense of a little bit of time overhead, which probably will not be significant anyway. And if you truly want to compact the statement:

import string
string1 = "SQUALALANOUSSOMESPARTISETJETEDTESTE"
taille = len(string1)
dictio = dict()
dictio = {letter: [] for letter in string.ascii_uppercase}
for index, letter in zip(range(taille), string1):
    dictio[letter].append(index)
print(dictio)

which could also be combined with the variable dict system.

Upvotes: 0

Nander Speerstra
Nander Speerstra

Reputation: 1526

There are several ways:

Fixed set of dict

string1 = "SQUALALANOUSSOMESPARTISETJETEDTESTE"
dictio = {'A':[],'B':[],'C':[],'D':[],'E':[],'F':[],'G':[],'H':[],'I':[],'J':[],'K':[],'L':[],'M':[],'N':[],'O':[],'P':[],'Q':[],'R':[],'S':[],'T':[],'U':[],'V':[],'W':[],'X':[],'Y':[],'Z':[]}

i = 0
for char in string1:
    dictio[char].append(i)
    i += 1

# {'L': [4, 6], 'A': [3, 5, 7, 18], 'Z': [], 'N': [8], 'J': [25], 'B': [], 'M': [14], 'C': [], 'S': [0, 11, 12, 16, 22, 32], 'K': [], 'W': [], 'Q': [1], 'O': [9, 13], 'R': [19], 'E': [15, 23, 26, 28, 31, 34], 'D': [29], 'P': [17], 'X': [], 'G': [], 'I': [21], 'H': [], 'Y': [], 'U': [2, 10], 'F': [], 'V': [], 'T': [20, 24, 27, 30, 33]}

Variable dict

string1 = "SQUALALANOUSSOMESPARTISETJETEDTESTE"
dictio = {}

i = 0
for char in string1:
    if char not in dictio:
        dictio[char] = []
    dictio[char].append(i)
    i += 1

The second version will give a dict with only the letters that are present.

Upvotes: 1

Elan
Elan

Reputation: 443

Not a beautiful solution, but it is how your program is designed: Make dictio = {'A':[],'B':[],'C':[],'D':[],...... and in the loop dictio[string1[a]].append(a)

Upvotes: 2

Łukasz Rogalski
Łukasz Rogalski

Reputation: 23223

You may use defaultdict to initialize keys implicitly with empty lists. After that enumerate over characters and append their indices to correct buckets.

from collections import defaultdict

word = "AZERTYUIOPAAAZ"

d = defaultdict(list)
for idx, letter in enumerate(word):
    d[letter].append(idx)

print d['A']  # [0,10,11,12]

Upvotes: 2

loganasherjones
loganasherjones

Reputation: 1060

The problem is your assignment statement:

dictio[string1[a]] = a

You are assigning an integer a to that particular value in the map. If you want to store them all, you would need to use a list. Something like the following:

for a in range(len(string1)):
    if dictio[string1[a]] is None:
        dictio[string1[a]] = [a]
    else:
        dictio[string1[a]].append(a)

Upvotes: 2

Related Questions