I would like to make an OrderedDict with a string for each key and a list of strings for each value.
from collections import OrderedDict
# Compare a dict with an OrderedDict
someDict = dict(a = ["foo","bar"], b = ["baz"])
someOrderedDict = OrderedDict([("a",("foo","bar")),("b",("baz"))])
I need to iterate over this dictionary with access to both the key and the values. On a vanilla dictionary, this is simply:
for k,v in someDict.items():
for eachv in v:
print("do something with key = " + k + " and value = " + eachv)
# returns the desired output:
# do something with key = a and value = foo
# do something with key = a and value = bar
# do something with key = b and value = baz
(If this can be done in a comprehension, please enlighten me -- I couldn't figure out how to do without losing access to the key.)
When I try this on the OrderedDict I get:
for k,v in someOrderedDict.items():
for eachv in v:
print("do something with key = " + k + " and value = " + eachv)
# results in undesirable splitting of value "baz" into ["b","a","z"]:
# do something with key = a and value = foo
# do something with key = a and value = bar
# do something with key = b and value = b
# do something with key = b and value = a
# do something with key = b and value = z
What am I doing wrong?
This is because you're assigning a string (("baz")) to the b key, rather than a tuple (("baz",)) or list of strings.
Instead of
someOrderedDict = OrderedDict([("a",("foo","bar")),("b",("baz"))])
try
someOrderedDict = OrderedDict([("a",("foo","bar")),("b",("baz",))])
(Note the new comma.)
You can add a , after "baz" so it can get interpreted as a tuple instead of a single str during the for loop:
someOrderedDict = OrderedDict([("a",("foo","bar")),("b",("baz",))])
Then, iteration works fine grabbing the single element of the tuple baz:
for k,v in someOrderedDict.items():
for eachv in v:
print("do something with key = " + k + " and value = " + eachv)
do something with key = b and value = baz
do something with key = a and value = foo
do something with key = a and value = bar
The same could be achieved by wrapping the values in []:
[("a", ["foo","bar"]),("b", ["baz"])]
Even better, if you already have the dictionary available, just expand (unpack) the dictionary someDict in someOrderedDict by utilizing the ** syntax:
someOrderedDict = OrderedDict(**someDict)
it works equally well and looks much more compact and clean.
Related
I'm trying to make a function to check whether a value added to a dictionary already exists.
If a value is already in the dictionary, it should print "Occupied" and not add the value to the existing key.
I have tried to get it to not append when the new input is similar, but it still adds the new input even though it is the same as the previous.
For example, if I add input_v as "Hi" --> XO = {'key': ["Hi"]}
If I were to put in "Hi" again, I then want it to say "Occupied", but as of right now it still adds to the dictionary.
XO = {'key': []}
def check_values(input_v):
value = input_v
print(XO)
if value in XO.values():
print("Occupied")
else:
XO['key'].append(value)
The issue is in the way you referenced the value of the 'key'. Use this:
XO = {'key': []}
def check_values(input_v):
value = input_v
global XO
#print(XO)
if value in XO['key']:
print("Occupied")
else:
XO['key'].append(value)
#print(XO)
d = dict()
for c in a:
if c not in d:
d[c] = 1
else:
print("Occupied")
Would this work? a is a list in this example.
How can I use dictionary as a conditional statement to change the value of the variable?
for example:
a = 20
dicta = {10:3, 20:2, 30:1}
#compare using first pair as the value of a, such that:
if a=10: assign a=3
if a=20: assign a=2
if a=30: assign a=1
Thankyou!
If you can be sure that the value of a is actually a key in the dict:
a = dicta[a]
or to have an additional check:
if a in dicta:
a = dicta[a]
else:
print("error, value {} not in dictionary".format(a))
Try this:
a = 20
for k, v in dicta.items():
if k == a:
a = v
break
This function takes a dictionary as an argument and translates the given string. However, it has become an endless loop. I can't for the life of me figure out how to make it work normally. For example: it is supposed to take a string "hi" and translates it into "[-]1"
def translate(glyphs):
string = input("Enter string to be translated: ").strip()
new = ''
for keys in glyphs:
ind = string.upper().find(keys)
while ind != -1: #while there exists a key in the string
if len(glyphs[string[ind].upper()]) > 1: #if there is more than one value for key
rand = randint(0, 1) #choose randomly
transChar = glyphs[keys][rand]
new = string[:ind] + transChar + string[ind+1:]
ind = string.upper().find(keys)
print("hi1")
else:
transChar = glyphs[keys][0]
new = string[:ind] + transChar + string[ind+1:]
ind = string.upper().find(keys)
print("hi")
return new
Any help would be appreciated!
Looks like your dictionary contains lists of possible translations as values, from which you make random choices, and upper-case keys. This list comprehension should work, then:
import random
new = ' '.join(random.choice(glyphs[word]) \
for word in input_string.upper().split())
I'm trying to write a looping function that prompts the user to enter a key from the first function and if it is is a key then it prints its value. If the word entered is not in the dictionary it returns "No entry".
What I have so far.
def read_ticker():
c = {}
with open('tickers.csv') as f:
for line in f:
items = [item.strip('"').strip() for item in line.split(",")]
c[items[0]] = items[1:]
print(c)
read_ticker()
d = read_ticker()
def ticker():
x = input('Ticker: ')
if x in d:
return x[c]
else:
return 'No entry'
ticker()
How can I return the value of the key entered in the second function?
You never return your dictionary in read_ticker, and it's unclear why you're calling the function twice.
Where print(c) is put return c.
And I think you want to index the dict instead of indexing the input.
Also, what is c that you're indexing with? This is undefined. I'm assuming this is meant to be the dictionary as defined in read_ticker. In which case you want d[x].
The dictionary c isn't global, although you could define it to be, so you can't access it in your other function by c (ignoring that the indexing is backwards even if possible). Instead, since the dictionary is local to the function read_ticker and modified there we return the dictionary and store it in the variable d.
Your read_ticker() function should return c:
def read_ticker():
c = {}
with open('tickers.csv') as f:
for line in f:
items = [item.strip('"').strip() for item in line.split(",")]
c[items[0]] = items[1:]
print(c)
return c
and then you can modify your ticker function as follows:
def ticker():
x = input('Ticker: ')
if x in d.keys():
return d[x]
else:
return 'No entry'
Your ticker function can use get, which allows you to give a value if the key doesn't exist, like this:
def ticker():
x = input('Ticker: ')
return d.get(x, "No entry")
This question already has an answer here:
Dictionary syntax error "can't assign to function call"
(1 answer)
Closed 9 months ago.
All,
I'm looping over a dictionary and counting the values that occur. To do this, I'm using the get method in the assignment statement for another dictionary. This returns a syntax error "can't assign to function call"
counts = {}
mydict = {'a':[1,2,5], 'b': [1,2,10]}
for key,value in mydict.iteritems():
counts(value[1]) = counts.get(value[1], 0) + 1
Why would the assignment try to point to the function, rather than the return value?
counts = {}
mydict = {'a':[1,2,5], 'b': [1,2,10]}
for key,value in mydict.iteritems():
counts[value[1]] = counts.get(value[1], 0) + 1
You need brackets, not parenthesis, to get an item from a dictionary.
Also, You're doing this the hard way.
from collections import defaultdict
# automatically start each count at zero
counts = defaultdict(int)
# we only need the values, not the keys
for value in mydict.itervalues():
# add one to the count for this item
counts[value[1]] += 1
or
# only on Python 2.7 or newer
from collections import Counter
counts = Counter(value[1] for value in mydict.itervalues())
Instead of counts(value[1]) = ... you want counts[value[1]] = ....
Change this:
counts(value[1])
to this:
counts[value[1]]
Code looks like this:
counts = {}
mydict = {'a':[1,2,5], 'b': [1,2,10]}
for key, value in mydict.iteritems():
counts[value[1]] = counts.get(value[1], 0) + 1
counts[value[1]] = counts.get(value[1], 0) + 1
should be
counts[value[1]] = counts.get(value[1], 0) + 1