I have this example code and nee to print out e.g. the second argument position alone, how do i do it?
def fun(a, b, c):
d = locals()
e = d
print (e)
print (locals())
fun(None, 2, None)
print(b) ... or I do not understand the question.
Update: If you mean to know the names of the arguments, you may want to use the standard module named inspect. Try the following:
#!python3
import inspect
def fun(a, b, c):
d = locals()
e = d
print (e)
print (locals())
# Here for observing from inside.
argspec = inspect.getfullargspec(fun)
print(argspec.args)
for arg in argspec.args:
print('argument', repr(arg), '=', repr(d[arg]))
# You can use indexing of the arg names if you like. Then the name
# is used for looking in locals() -- here you have it in d.
args = argspec.args
print(d[args[0]])
print(d[args[1]])
print(d[args[2]])
fun(None, 2, None)
# Here for observing from outside.
argspec = inspect.getfullargspec(fun)
print(argspec.args)
for n, arg in enumerate(argspec.args, 1):
print('argument', n, 'is named', repr(arg))
You should observe:
{'a': None, 'b': 2, 'c': None}
{'d': {...}, 'e': {...}, 'a': None, 'b': 2, 'c': None}
['a', 'b', 'c']
argument 'a' = None
argument 'b' = 2
argument 'c' = None
None
2
None
['a', 'b', 'c']
argument 1 is named 'a'
argument 2 is named 'b'
argument 3 is named 'c'
See the doc http://docs.python.org/3.3/library/inspect.html#inspect.getfullargspec
Related
I have a text file below:
A test B echo C delete
A test B echo C delete D modify
A test B echo C delete
I want to parse the text file above, translate to list of list, and then to a dictionary.
Expected list of list is:
[['A', 'test', 'B', 'echo', 'C', 'delete'], ['A', 'test', 'B', 'echo', 'C', 'delete', 'D', 'modify'], ['A', 'test', 'B', 'echo', 'C', 'delete']]
Final result for dictionary is:
[{'A':'test','B':'echo','C':'delete'},{'A':'test','B':'echo','C':'delete','D': 'modify'},{'A':'test', 'B':'echo', 'C':'delete'}]
This is my script:
#!/usr/bin/python3
def listToDict(list):
listDict = {list[i]: list[i + 1] for i in range (0, len(list), 2)}
return listDict
def parse_file(filepath):
string_to_listoflist = []
with open(filepath, 'r') as file_object:
lines = file_object.readlines()
for line in lines:
string_to_listoflist.append(line.rstrip().split())
dictionary = listToDict(string_to_listoflist)
print(dictionary)
if __name__ == '__main__':
filepath = 'log.txt'
parse_file(filepath)
with the above script will produce an error below:
Traceback (most recent call last):
File "parse.py", line 19, in <module>
parse_file(filepath)
File "parse.py", line 14, in parse_file
dictionary = listToDict(string_to_listoflist)
File "parse.py", line 4, in listToDict
listDict = {list[i]: list[i + 1] for i in range (0, len(list), 2)}
File "parse.py", line 4, in <dictcomp>
listDict = {list[i]: list[i + 1] for i in range (0, len(list), 2)}
TypeError: unhashable type: 'list'
Now I create another loop in the list of list below:
#!/usr/bin/python3
def listToDict(list):
listDict = {list[i]: list[i + 1] for i in range (0, len(list), 2)}
return listDict
def parse_file(filepath):
string_to_listoflist = []
dictionary = {}
with open(filepath, 'r') as file_object:
lines = file_object.readlines()
for line in lines:
string_to_listoflist.append(line.rstrip().split())
for e in string_to_listoflist:
dictionary = listToDict(e)
print(dictionary)
if __name__ == '__main__':
filepath = 'log.txt'
parse_file(filepath)
The script above will produce unexpected result even I define the dictionary variable before the loop:
{'A': 'test', 'B': 'echo', 'C': 'delete'}
Then change the position of print command as below:
#!/usr/bin/python3
def listToDict(list):
listDict = {list[i]: list[i + 1] for i in range (0, len(list), 2)}
return listDict
def parse_file(filepath):
string_to_listoflist = []
dictionary = {}
with open(filepath, 'r') as file_object:
lines = file_object.readlines()
for line in lines:
string_to_listoflist.append(line.rstrip().split())
for e in string_to_listoflist:
dictionary = listToDict(e)
print(dictionary)
if __name__ == '__main__':
filepath = 'log.txt'
parse_file(filepath)
Unexpected result for the script above is:
{'A': 'test', 'B': 'echo', 'C': 'delete'}
{'A': 'test', 'B': 'echo', 'C': 'delete', 'D': 'modify'}
{'A': 'test', 'B': 'echo', 'C': 'delete'}
Can anyone help how to resolve my issue?
Thanks
In your first attempt, your variable string_to_listoflist is a list of lists.
When you pass it to your function listToDict, the function iterates on the parent level of the list instead of iterating over each list within the parent list. Thus, the first entry attempted in the dictionary is
['A', 'test', 'B', 'echo', 'C', 'delete']:['A', 'test', 'B', 'echo', 'C', 'delete', 'D', 'modify']
rather than your intended
'A':'test'
This causes the error you observe TypeError: unhashable type: 'list' since a list (mutable) is attempted to be used as a key in a dictionary, which requires immutable keys.
Adding the extra loop surrounding each element of the parent list is the correct way to resolve this. However, if you want your final result to be inside a list, you simply need to append the result to a list.
In other words, perhaps the following
dictionaries=[]
for e in string_to_listoflist:
dictionary = listToDict(e)
dictionaries.append(dictionary)
print(dictionaries)
You can use re module to obtain your desired dict.
For example:
import re
with open('file.txt', 'r') as f_in:
out = [dict(re.findall(r'([A-Z]+) ([^\s]+)', line)) for line in f_in]
print(out)
Prints:
[{'A': 'test', 'B': 'echo', 'C': 'delete'}, {'A': 'test', 'B': 'echo', 'C': 'delete', 'D': 'modify'}, {'A': 'test', 'B': 'echo', 'C': 'delete'}]
I have a requirement to make a function which takes n number of arguments and returns the values in a dictionary data structure.
For example:
Input: it will take arguments in a list
list =['a','b','c']
this list can go to n number of values.
Output: Function returns the value as
{'a':[1,2,'x'],
'b':[3,4,'y'],
'c':[5,6,'z']
}
I have used python 3.x for the same and tried below code, which gave an error unhashable type: 'list':
def Myfunc(*args):
dir={}
for x in args:
lst=[1,2,3] # This list has static value here but in actual code,
# I am generating some dynamic value. Length of list always 3.
dir[x]=lst
z=Myfunct(['a','b','c'])
*args is meant to be used to pass variable number of arguments to the function. So in your case if you did
z = MyFunct('a', 'b', 'c')
then it would work as you expected.
You're actually passing just one argument so the for loop is evaluating just once and with x = ['a', 'b', 'c']
You should change the declaration to:
def MyFunct(arg):
Did you mean to pass a list as in the code below?
Also, please note that your function doesn't return anything.
I changed name of the variable from dir to d, because dir is a built-in python function:
https://docs.python.org/3/library/functions.html?highlight=dir#dir
In [31]: def Myfunc(*args):
...: d={}
...: for x in args:
...: lst=[1,2,3] #this list has static value here but in actual code, I am generating some dynamic value. Length of list always 3.
...: d[x]=lst
...: return d
...:
In [32]: z = Myfunc(*['a','b','c'])
In [33]: z
Out[33]: {'a': [1, 2, 3], 'b': [1, 2, 3], 'c': [1, 2, 3]}
This is a MWE that shows what I want to obtain but using a for loop:
a = {'a':1, 'b':2, 'c':3, 'd':4}
b = []
c = []
for key, value in a.items():
b.append(key)
c.append(value)
print(b) # ['a', 'b', 'c', 'd']
print(c) # [1, 2, 3, 4]
I want to obtain the same result in one line using list comprehension.
b,c = [(key, value) for key, value in a.items()] results in an unpack error because it assign to b and c, respectively, the first and second item of a and then it doesn't know where unpack the other items. b,c = [key, value for key, value in a.items()] results again in an error, a syntax one.
b, c = map(list, zip(*a.items()))
print(b)
print(c)
This outputs:
['a', 'b', 'c', 'd']
[1, 2, 3, 4]
Is there a more elegant way to toggle between two strings or integers in Python 3?
x={"A":"B", "B":"A"}[x]
The values can be non-boolean, like string or integer.
Let's suppose that we want to toggle between "A" and "B" and the variable name is x.
In other words: if x = "A" then the result should be x = "B" and if x = "B" then the result should be x = "A".
input:
x="B"
output:
x="A"
Using a dict is already pretty smart. Here is an alternative:
x = 'B' if x == 'A' else 'A'
You can write something like that:
def toggle(x):
x['A'], x['B'] = x['B'], x['A']
x = {'A': 'B', 'B': 'A'}
or that:
def toggle(x):
x.update(dict(zip(x.keys(), list(x.values())[::-1])))
x = {'A': 'B', 'B': 'A'}
print(x)
toggle(x)
print(x)
toggle(x)
print(x)
OUTPUT:
{'A': 'B', 'B': 'A'}
{'A': 'A', 'B': 'B'}
{'A': 'B', 'B': 'A'}
for example:
s = 'abc'
number = 1
I want to write a function that return a dict like {'a': {'a', 'b'}, 'b': {'a', 'b', 'c'}, 'c': {'b', 'c'}}
number determine how many adjacent letters next to the current key.
def test(s : str, num : int) -> {str:{str}}:
dict = {}
for word in s:
dict[word] = word
return dict
i can only write one return the same key and value. any suggestions?
Try something like:
>>> s='abc'
>>> n=1
>>> {c:{e for e in[s[i-n:i],c,s[i+1:i+1+n]] if e} for i, c in enumerate(s)}
{'a': {'a', 'b'}, 'b': {'a', 'b', 'c'}, 'c': {'b', 'c'}}