Define elements of list as list [duplicate] - python

This question already has answers here:
How can I create multiple variables from a list of strings? [duplicate]
(2 answers)
Closed 1 year ago.
I have a list of variables like:
master = ['A', 'B', 'C', 'D']
I want to loop over master and create n lists where n is number of variables.
Also the names of the lists should be by the name of the elements
I tried:
for i in master:
i = list()
print(i)
but here the list doesn't have any name

If you want to assign a name (that is the same as the element), you probably need a dictionary.
from collections import defaultdict
master = ['A', 'B', 'C', 'D']
d = defaultdict(list)
for elem in master:
d[elem].append(elem)
print(d["A"]) # ["A"]
You can also do this with dict-comprehension.
d1 = {el: el for el in master}
print(d1["A"]) # "A"
d2 = {el: [el] for el in master}
print(d2["A"]) # ["A"]

You can use python dictionaries for this . For example :
thisdict = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
print(thisdict)
this will print {'brand': 'Ford', 'model': 'Mustang', 'year': 1964}
Please visit here for more explanations : here

Related

Create Dictionary with Variable Name Values [duplicate]

This question already has answers here:
How can I select a variable by (string) name?
(5 answers)
Closed 8 months ago.
I am trying to figure out how to best create a python dictionary where the values are variable names
e.x.
ruleLst = ["gender+brand","sport+gender","sport+gender+brand"]
for i in ruleLst:
new_values = i.split("+")
rules.update({i:new_values})
rules
returns:
{
'gender+brand': ['gender', 'brand'],
'sport+gender': ['sport', 'gender'],
'sport+gender+brand': ['sport', 'gender', 'brand']
}
What I try to output is:
{
'gender+brand': [gender, brand],
'sport+gender': [sport, gender],
'sport+gender+brand': [sport, gender, brand]
}
Where gender, brand, sport are lists defined in the code before ruleLst is defined.
You can use list comprehension like:
ruleLst = ["gender+brand","sport+gender","sport+gender+brand"]
gender = ["M", "F"]
sport = ["basket", "volleyball"]
brand = [1, 2]
a = {i: [globals()[j] for j in i.split("+")] for i in ruleLst}
print(a)
and output:
{
'gender+brand': [['M', 'F'], [1, 2]],
'sport+gender': [['basket', 'volleyball'], ['M', 'F']],
'sport+gender+brand': [['basket', 'volleyball'], ['M', 'F'], [1, 2]]
}
Reference:
Create a dictionary with list comprehension
How to get the value of a variable given its name in a string?
Try using globals()[new_values[0]] and globals()[new_values[1]] instead of new_values to get the variables value.
Like this:
ruleLst = ["gender+brand","sport+gender","sport+gender+brand"]
rules = {}
gender = ["male", "female"]
sport = ["basket", "volleyball"]
brand = ["x", "y"]
for i in ruleLst:
new_values = i.split("+")
rules.update({i:[globals()[new_values[0]], globals()[new_values[1]]]})
print(rules)
You could solve this with the map function like this. By casting it as a dict you'll get the dictonary you want.
rules = dict(map(lambda elem: [elem, elem.split('+')], ruleLst))

How to get the name of a nested list? [duplicate]

This question already has answers here:
How can I get the name of an object?
(18 answers)
Closed 1 year ago.
I'm wondering if something like this is possible. Let's suppose this snippet of code:
area = ["A","B","C"]
level = ["L1","L2","L3"]
sector = [area, level]
print(sector)
print(sector[1])
Output:
Print 1: [['A', 'B', 'C'], ['L1', 'L2', 'L3']]
Print 2: ['L1', 'L2', 'L3']
The first print is OK for me. It shows the lists and their elements.
However, for the second print I would like to have the name of the list instead of its elements. In this case level
Is that possible?
What you can do though, is use a dictionnary:
di = {"area": ["A", "B", "C"], "level": ["L1", "L2", "L3"]}
di["area"]
Output :
["A", "B", "C"]
You could compare the id:
for sec in sector:
if id(sec) == id(area):
print('area')
elif id(sec) == id(level):
print('level')
etc.
However, this is a dubious way to go. Why do you need this?
Make it into a Dictionary of Lists instead of a List of Lists:
area = ["A","B","C"]
level = ["L1","L2","L3"]
sectors = {
"area": area,
"level": level
}
print(sectors["level"])
print(sectors["area"])
""" some other useful dict methods below """
print(sectors.keys())
print(sectors.values())
print(sectors.items())
You can use a dictionary for your usecase.
You can make the name of the variables as key and lists as values.
Try this:
area = ["A","B","C"]
level = ["L1","L2","L3"]
sector = {"area":area, "level":level}
print(list(sector.values()))
print(list(sector.keys()))
Outputs:
[['A', 'B', 'C'], ['L1', 'L2', 'L3']]
['area', 'level']

Best approach for converting list of nested dictionaries to a single dictionary with aggregate functions

I've looked through a lot of solutions on this topic, but I have been unable to adapt my case to a performant one. Suppose I have a list of dictionaries stored as:
db_data = [
{
"start_time": "2020-04-20T17:55:54.000-00:00",
"results": {
"key_1": ["a","b","c","d"],
"key_2": ["a","b","c","d"],
"key_3": ["a","b","c","d"]
}
},
{
"start_time": "2020-04-20T18:32:27.000-00:00",
"results": {
"key_1": ["a","b","c","d"],
"key_2": ["a","b","e","f"],
"key_3": ["a","e","f","g"]
}
},
{
"start_time": "2020-04-21T17:55:54.000-00:00",
"results": {
"key_1": ["a","b","c"],
"key_2": ["a"],
"key_3": ["a","b","c","d"]
}
},
{
"start_time": "2020-04-21T18:32:27.000-00:00",
"results": {
"key_1": ["a","b","c"],
"key_2": ["b"],
"key_3": ["a"]
}
}
]
I am trying to get a data aggregation from the list output as a dictionary, with the key values of the results object as the keys of the output, and the size of the set of unique values for each date for each key.
I am attempting to aggregate the data by date value, and outputting the count of unique values for each key for each day.
Expected output is something like:
{
"key_1": {
"2020-04-20": 4,
"2020-04-21": 3
},
"key_2": {
"2020-04-20": 6,
"2020-04-21": 2
},
"key_3": {
"2020-04-20": 7,
"2020-04-21": 4
}
}
What I have tried so far is using defaultdict and loops to aggregate the data. This takes a very long time unfortunately:
from datetime import datetime
grouped_data = defaultdict(dict)
for item in db_data:
group = item['start_time'].strftime('%-b %-d, %Y')
for k, v in item['results'].items():
if group not in grouped_data[k].keys():
grouped_data[k][group] = []
grouped_data[k][group] = list(set(v + grouped_data[k][group]))
for k, v in grouped_data.items():
grouped_data[k] = {x:len(y) for x, y in v.items()}
print(grouped_data)
Any help or guidance is appreciated. I have read that pandas might help here, but I am not quite sure how to adapt this use case.
Edit
I am not sure why this was closed so fast. I am just looking for some advice on how to increase performance. I would appreciate if this could get re-opened.
The code below has a generator assigned to flat_list that flattens the original dictionary out into a list of tuples. Then the defaultdict is set up to be a dictionary with two levels of key, key and date, for which the value is a set. The set is updated for each key/date so it contains a list of unique items. This is vaguely similar to the example code, but it should be more efficient.
>>> from collections import defaultdict
>>> from functools import partial
>>>
>>> flat_list = ((key, db_item['start_time'][:10], results)
... for db_item in db_data
... for key, results in db_item['results'].items())
>>>
>>> d = defaultdict(partial(defaultdict, set))
>>>
>>> for key, date, li in flat_list:
... d[key][date].update(li)
...
Testing it out, we get the same number of list items per key/date as the counts in the example:
defaultdict(..., {'key_1': defaultdict(<class 'set'>, {
'2020-04-20': {'a', 'd', 'b', 'c'},
'2020-04-21': {'a', 'b', 'c'}}),
'key_2': defaultdict(<class 'set'>, {
'2020-04-20': {'a', 'f', 'd', 'c', 'b', 'e'},
'2020-04-21': {'a', 'b'}}),
'key_3': defaultdict(<class 'set'>, {
'2020-04-20': {'a', 'f', 'd', 'c', 'b', 'g', 'e'},
'2020-04-21': {'a', 'd', 'b', 'c'}})})
If you prefer the value to be a count of list items, you can just do len(d[key][date]).
Since flat_list is a generator, it doesn't do all its looping separately, but does it in conjunction with the loop that builds the dictionary. So in that way it's efficient.
[Update] I'm not seeing the performance gain on my system with CPython 3.8 indicated in the comments. The algorithm here is only marginally faster than the example in the question after fixing the line with item['start_time'].strftime('%-b %-d, %Y') to item['start_time'][:10].
With that said, efficiency is addressed by taking advantage of the set. Operations on a set are very fast, and we're just updating its elements. We don't need to test a list for group membership first. Checking lists for membership is a very slow operation that can really add up in loops. The time-complexity for checking a list for membership is O(n) per item added, whereas set operations are O(1) per item added.
Reference on time complexity of python data types and operations: https://wiki.python.org/moin/TimeComplexity

Create a nested tree from list

From a list of lists, I would like to create a nested dictionary of which the keys would point to the next value in the sublist. In addition, I would like to count the number of times a sequence of sublist values occurred.
Example:
From a list of lists as such:
[['a', 'b', 'c'],
['a', 'c'],
['b']]
I would like to create a nested dictionary as such:
{
'a': {
{'b':
{
'c':{}
'count_a_b_c': 1
}
'count_a_b*': 1
},
{'c': {},
'count_a_c': 1
}
'count_a*': 2
},
{
'b':{},
'count_b':1
}
}
Please note that the names of the keys for counts do not matter, they were named as such for illustration.
i was curious how i would do this and came up with this:
lst = [['a', 'b', 'c'],
['a', 'c'],
['b']]
tree = {}
for branch in lst:
count_str = 'count_*'
last_node = branch[-1]
cur_tree = tree
for node in branch:
if node == last_node:
count_str = count_str[:-2] + f'_{node}'
else:
count_str = count_str[:-2] + f'_{node}_*'
cur_tree[count_str] = cur_tree.get(count_str, 0) + 1
cur_tree = cur_tree.setdefault(node, {})
nothing special happening here...
for your example:
import json
print(json.dumps(tree, sort_keys=True, indent=4))
produces:
{
"a": {
"b": {
"c": {},
"count_a_b_c": 1
},
"c": {},
"count_a_b_*": 1,
"count_a_c": 1
},
"b": {},
"count_a_*": 2,
"count_b": 1
}
it does not exactly reproduce what you imagine - but that is in part due to the fact that your desired result is not a valid python dictionary...
but it may be a starting point for you to solve your problem.

Python - Converting list to dict pairwise [duplicate]

This question already has answers here:
Iterating over every two elements in a list [duplicate]
(22 answers)
Closed 4 years ago.
I have a list that looks like this:
mylist = [1, 'a', 2, 'b', 3, 'c']
and would like to end up with a dictionary:
mydict = {
'a': 1,
'b': 2,
'c': 3,}
At the moment I'm achieving it like so:
mydict = {}
for i, k in enumerate(mylist):
if i == len(mylist)/2:
break
v = 2 * i
mydict[mylist[v+1]] = mylist[v]
Is there a more pythonic way of achieving the same thing? I looked up the itertools reference but didn't find anything in particular that would help with the above.
Note: I'm happy with what I have in terms of achieving the goal, but am curious if there is anything that would be more commonly used in such a situation.
Try this
# keys
k = mylist[1::2]
# values
v = mylist[::2]
# dictionary
mydict = dict(zip(k, v))

Categories

Resources