Lua's "Generic For Loop" for Python? - python

So, I've been searching endlessly for something similiar to Lua's "Generic For Loop" in Python.
I've been working on a simple text based game in Python, and I've been working with dictionaries a lot.
Here is something I'm looking for (in Lua):
Dictionary = {
"Red" = "There is some red paint on the walls.",
"Green" = "There is a little bit of green paint on the floor.",
}
for i, v in pairs(Dictionary) do
print(i, v)
end
What this will do is, go through the dictionary, then print out the INDEX and the VALUE. How would I do something like this in Python?
I know there is this:
for i in Dictionary:
print(i)
But that just prints the INDEX. I would like to access both the INDEX and the VALUE. Something like:
for i, v in Dictionary:
print(i, v)
Any help is appreciated.

You're looking for items. Iterating over a dict just gives you the keys, so you'd have to do:
for key in my_dict:
x = my_dict[key]
What you want is this:
for key, value in my_dict.items():
# do something

two ways:
for i, v in Dictionary.items():
print(i, v) #outputs pairs as key value
for tup in Dictionary.items(): #same thing
print(tup) # outputs pairs as (key,value)
or
for key in Dictionary:
print(key,Dictionary[key])
EDIT RESPONSE TO COMMENT:
>>> d = {1:1,2:2,3:3,4:4}
>>> for item in d.items(): print(item)
(1, 1)
(2, 2)
(3, 3)
(4, 4)
>>> for key,val in d.items(): print(key,val)
1 1
2 2
3 3
4 4
this is because in the first loop, item is a tuple and the __repr__ for a tuple has the brackets and commas as part of it where as the second loop splits the tuple into two seperate variables. print then automatically adds a space delimiter in between each parameter passed in the print function.
As explained by Two-Bit Alchemist:
In case it's not entirely clear still, in the tup formulation you'd access the key and value as tup[0] and tup[1], respectively. for key, val in my_dict.items(): ... and for tup in my_dict.items(): key, val = tup is the same setup. The point is you can use tuple unpacking just fine inline in a for loop.

The items method (or in Py2, viewitems or iteritems to avoid making a whole new list containing copies of the dict key/value pairs) is the way to go:
for k, v in Dictionary.items(): # For performance, use .viewitems() on Py2.7, .items() on Py3.x
print(k, v)

Related

Trouble with dict

Trying to write a program in python to display inventory and number of each item in inventory, but having difficulty pulling values from dict...
Using Python 3.5 on Win10, through default Python editor
From chapter 5 sample problem of "Automate the Boring Things with Python"
i={'color':'red','gold':3}
def bP(n):
inv=''
for v in n:
print (str(n)+':'+str(n[v])) #Problem is first print not displaying value
bP(i)
You can iterate dictionary by key-value pair too. Check the manual. Here is an example of it.
for k, v in dict.items():
print(k, v)
i={'color':'red','gold':3}
def bP(n):
inv=''
for key,value in n.items():
print (str(key)+':'+str(value))
bP(i)
when you iterate dict then should use items() method
Consider the following example:
d={'color':'red','gold':3}
for key,value in d.items():
print(key,value)
output:
gold 3
color red
d.items() outputs a key,value pair.
Also,
for item in d.values():
print(item)
output:
3
red
But,
for key in d.keys():
print(key)
output:
gold
color
However just doing this gives the same result as above,
for key in d:
print(key)
output:
gold
color
So in your case,
for v in n:
print (str(n)+':'+str(n[v]))
should be,
for v in n:
print (str(v)+':'+str(n[v]) )
if variables made more sense would be something like,
for key in my_dict:
print (str(key)+':'+str(my_dict[key])) #my_dict[key] is value
You are trying to print str(n) which is your dict. Alternatively, you can loop through items of the dictionary as the following:
for k, v in n.items():
print('{}:{}'.format(k, v))
While in your case, you can fix it by changing str(n):
for v in n:
print('{}:{}'.format(v, n[v]))

How to Get a Key value from a dictionary whose values are lists?

I have a dictionary where each key has several lists of data as its values like this
myDict = {'data1' : ['data_d','dataD']['data_e','dataE']['data_f','dataF']}
I want to be able to input one of the values in the list and then be given the key. This is so I can get the other value in the list now that I have the key.
I've tried
dataKey = (list(myDict.keys())[list(myDict.values()).index(dataD)])
but that didn't work
I've also tried
for k, v in myDict.items():
if 'dataD' in v:
print k
but that didn't work as well.
Side question, in the questions that I've looked through, I see people using the variable k and v a lot even without the OP mentioning them, so I am wondering if k and v are already set variable in dictionaries?
Your second attempt was almost right, but a nested for loop is needed to traverse the list-of-lists:
myDict = {'data1' : [['data_d','dataD'], ['data_e','dataE'], ['data_f','dataF']]}
for key, value in myDict.items():
for sublist in value:
if 'dataD' in sublist:
print(key) # -> data1
Using variables named k, and v with dictionaries is purely optional and aren't special properties—other than being very short abbreviations for "key" and "value".
Note that if only one match is ever expected to occur, the code could be made more efficient by stopping the search after one is found. Here's one way of doing that:
target = 'dataD'
try:
for key, value in myDict.items():
for sublist in value:
if target in sublist:
print(key) # -> data1
raise StopIteration # found, so quit searching
except StopIteration:
pass # found
else:
print('{} not found'.format(target))
if they are all going to be lists then you can do something like this (if i am understanding correctly)
myDict = {
'data1': [['data_d','dataD'], ['data_e','dataE'], ['data_f','dataF']],
}
def find(dic, item):
for k, v in dic.items():
for ls in v:
if item in ls:
return k
return False
print(find(myDict, "data_d"))
# OUT [data1]

Find non-Empty value in dict

I have a dict like this:
d = {'first':'', 'second':'', 'third':'value', 'fourth':''}
and I want to find first non-empty value (and it's name, in this example 'third'). There may be more than one non-empty value, but I only want the first one I find.
How can I do this?
Use an OrderedDict which preserves the order of elements. Then loop over them and find the first that isn't empty:
from collections import OrderedDict
d = OrderedDict()
# fill d
for key, value in d.items():
if value:
print(key, " is not empty!")
You could use next (dictionaries are unordered - this somewhat changed in Python 3.6 but that's only an implementation detail currently) to get one "not-empty" key-value pair:
>>> next((k, v) for k, v in d.items() if v)
('third', 'value')
Like this?
def none_empty_finder(dict):
for e in dict:
if dict[e] != '':
return [e,dict[e]]
d = {'first':'', 'second':'', 'third':'value', 'fourth':''}
for k, v in d.items():
if v!='':
return k, v
Edit 1
from the comment if the value is None or '' we better use if v: instead of if v!=''. if v!='' only check the '' and skip others
You can find empty elements and make a list of them:
non_empty_list = [(k,v) for k,v in a.items() if v]
By using list comprehension, you can list all the non-empty values and then fetch the 0th value:
[val for key, val in d.items() if val][0]

Delete items in a dictionary with values that don't equal the highest value in Python

Essentially I want to delete every key in a dictionary if its value doesn't equal the highest value.
Let's say this is the dictionary:
myDict = {"Bob": 1, "Bill": 5, "Barry": 4, "Steve": 5}
I'm able to sort it by value using this:
myDict = sorted(myDict, key=myDict.get, reverse=True)
Now I want to remove any key in the dictionary that doesn't equal the highest value (in this case '5'). To end up with this:
myDict = {"Bill": 5, "Steve": 5}
I've tried using this for loop:
for item, v in myDict:
if v < myDict[0]:
del myDict[v]
But I get this error:
ValueError: too many values to unpack (expected 2)
This is a) my first time posting here, and b) I've only been learning Python for a few months so I'm sorry if I've made any stupid mistakes.
for item, v in myDict just give you keys mydict, and you are collecting that key in item, v that's why,
use myDict.items() or myDict.iteritems().
for item, v in myDict.iteritems():
if v < myDict[0]:
del myDict[v]
To get Highest value of myDict
max(myDict.values())
To delete keys from Dict never change the iterator you are iterating on, it will give you RuntimeError. So copy it in another variable and change previous one as Anand S Kumar suggested.
You should never alter the object you're iterating over, that usually yields unexpected results (internal pointers get shifted and you miss elements in your iteration and such). You best gather the keys you want to delete and then remove the keys in a separate iteration:
keys = [k for k in myDict.keys() if myDict[k] == max(myDict.values())];
for k in keys: del myDict[k];
It might be best to put the max expression in a variable too so it doesn't get evaluated multiple times. Not sure if Python's able to optimize that for you (probably not).
You can use dictionary comprehension to create a new dictionary:
newDict = {k: v for k,v in myDict.items() if v == max(myDict.values())}
The output for newDict:
{'Steve': 5, 'Bill': 5}

Modifying tuple element from the dictionary

I have a following dictionary as input:
my_dict[(1, 2)] = (3,4)
Now what I want to have convert it to is:
my_dict[(1,2)] = (3,40)
What is the best and efficient way to do this?
The dictionary itself is not very big...
I could probably do something like:
for (var1,var2),(var3,var) in my_dict.iteritems():
del my_dict[(var1,var2)]
my_dict[(var1,var2)] = (var3, var5)
but I don't think its right approach as I modify the dictionary in a loop.
You can just assign directly to the key; no need to delete the key first.
You could loop over the dictionary, yielding keys (your tuples); no need to unpack these even:
for key in my_dict:
my_dict[key] = (my_dict[key][0], var5)
or include the values:
for key, (val1, _) in my_dict.iteritems():
my_dict[key] = (val1, var5)
This unpacks just the value so you can reuse the first element. I've used _ as the name for the second value element to document it'll be ignored in the loop.
my_dict={}
my_dict[(1, 2)] = (3,4)
for i,val in my_dict.items():
my_dict[i]=(3,24)
print my_dict
#output {(1, 2): (3, 24)}
other way.
for i in my_dict.keys():
my_dict[i]=(3,24)
print my_dict
also
for i in my_dict:
my_dict[i]=(3,24)
print my_dict
You could do something like this:
my_dict[(1, 2)] = (3,4)
my_Dict2={i:(j[0],j[1]*10) for i,j in my_Dict.items()}
But I'm not sure if this is what your looking for since 'var5' in your code snippet is not defined. However, if you need to modify a tuple, there is probably a better type to use.

Categories

Resources