Sorry, I couldn't think of a better title for my question.
So I'm a starter at Python and I really trying to learn how to use it. My current problem deals with creating a simple way to reduce the results received from a python query.
If I understand what I'm dealing with, the LDAP query returns a List of a List of Dictionary where value in the Dictionary is a List. That's a lotta stuff there to traverse through so I figured there has to be a nice magical python way to convert this to a List of a Dictionary where the value of the Dictionary is just a simple string.
Currently, my code just simply to get the List of Dictionary but I still have the Dictionary values as a List themselves
for item in data:
results.append(item[1])
Once again, I'm a beginner so I don't really understand what to do from there. I'm also using Django if that's gonna help anyone understand my plight.
Edit (added data example):
The Structure is kinda like this:
data[index][1] = {'uid': ['restest'], 'mail': [''], 'givenName': ['Research'], 'cn': ['Research Test Account'], 'sn': ['Account']}
I'd like it to be instead of 'givenName': ['Research'] to be 'givenName': 'Reaseach'
Haha I'm not sure you ever want such a complicated data structure around. Consider refactoring your code to make your data structures easier to understand. Read: object-oriented programming, classes, functional programming principles.
Here's the answer if you just want to do it for a single dictionary:
data = {k:v[0] for (k,v) in data.items()}
Here it is in action:
>>> data = {'uid': ['restest'], 'mail': [''], 'givenName': ['Research'], 'cn': ['Research Test Account'], 'sn': ['Account']}
>>> data
{'mail': [''], 'sn': ['Account'], 'givenName': ['Research'], 'uid': ['restest'], 'cn': ['Research Test Account']}
>>> data = {k:v[0] for (k,v) in data.items()}
>>> data
{'mail': '', 'givenName': 'Research', 'cn': 'Research Test Account', 'sn': 'Account', 'uid': 'restest'}
All you're doing is re-mapping your dictionary to the first item of each list. If you want to iterate through all the levels of your structure and do this, just nest the above inside some list comprehensions:
[[[{k:v[0] for (k,v) in change_dict.items()} for change_dict in list_of_dicts]
for list_of_dicts in list_of_lists]
for list_of_lists in mydata]
It's not so bad to nest so many list comprehensions when you're only doing something to a "leaf" element in your data, but this is gonna get really messy if you try to manipulate your data structures at every level. See my comment at the beginning.
Related
I would like create a object ID in python, I explain:
I know that exist mysql, sqlite, mongoDB, etc... But I would like at least create a object ID for store data in json.
Before I was putting the json info inside of a list and the ID was the index of this json in the list, for example:
data = [{"name": userName}]
data[0]["id"] = len(data) - 1
Then I realize that was wrong and obviously dont look like objectID, then I thought in that the ID can be the Date and Time together, but I thought was wrong too, so, I would like know the best way for make like a objectID, that represent this json inside the list. this list will be more longer, is for users or clients (is just a personal project). And how can be a example of a method for create the ID
Thanks so much, hope I explained good.
If you just want to create a locally unique value, you could use a really simple autoincrement approach.
data = [
{"name": "Bill"},
{"name": "Javier"},
{"name": "Jane"},
{"name": "Xi"},
{"name": "Nosferatu"},
]
current_id = 1
for record in data:
record["id"] = current_id
current_id += 1
print(record)
# {'name': 'Bill', 'id': 1}
# {'name': 'Javier', 'id': 2}
# {'name': 'Jane', 'id': 3}
# {'name': 'Xi', 'id': 4}
# {'name': 'Nosferatu', 'id': 5}
To add a new value if you're not initializing like this, you can get the last one with max(d.get("id", 0) for d in data).
This may cause various problems depending on your use case. If you don't want to worry about that, you could also throw UUIDs at it; they're heavier but easy to generate with reasonable confidence of uniqueness.
from uuid import uuid4
data = [{"name": "Conan the Librarian"}]
data[0]["id"] = str(uuid4())
print(data)
# 'id' will be different each time; example:
# [{'name': 'Conan the Librarian', 'id': '85bb4db9-c450-46e3-a027-cb573a09f3e3'}]
Without knowing your actual use case, though, it's impossible to say whether one, either, or both of these approaches would be useful or appropriate.
I have a dictionary with a key and a pair of values, the values are stored in a List. But i'm keeping the list empty so i can .append its values ,i cant seem to be able to do this
>>>myDict = {'Numbers':[]}
>>>myDict['Numbers'[1].append(user_inputs)
doesn't seem to work, returns an error . How do i refer to the list in myDict so i can append its values.
Also is it possible to have a dictionary inside a list and also have another list inside? if so? what is its syntax or can you recommend anyother way i can do this
>>>myDict2 = {'Names': [{'first name':[],'Second name':[]}]}
do i change the second nested list to a tuple?? Please lets keep it to PYTHON 2.7
You get an error because your syntax is wrong. The following appends to the list value for the 'Numbers' key:
myDict['Numbers'].append(user_inputs)
You can nest Python objects arbitrarily; your myDict2 syntax is entirely correct. Only the keys need to be immutable (so a tuple vs. a list), but your keys are all strings:
>>> myDict2 = {'Names': [{'first name':[],'Second name':[]}]}
>>> myDict2['Names']
[{'first name': [], 'Second name': []}]
>>> myDict2['Names'][0]
{'first name': [], 'Second name': []}
>>> myDict2['Names'][0]['first name']
[]
You should access the list with myDict['Numbers']:
>>>myDict['Numbers'].append(user_inputs)
You can have dicts inside of a list.
The only catch is that dictionary keys have to be immutable, so you can't have dicts or lists as keys.
You may want to look into the json library, which supports a mix of nested dictionaries and lists.
In addition, you may also be interested in the setdefault method of the dictionary class.
Format is something like:
new_dict = dict()
some_list = ['1', '2', '3', ...]
for idx, val in enumerate(some_list):
something = get_something(idx)
new_dict.setdefault(val, []).append(something)
Lets say I have a list
demo = [['Adam', 'Chicago', 'Male', 'Bears'], ['Brandon', 'Miami', 'Male', 'Dolphins']]
I want to make a list of dictionaries using a comprehension that looks like
[{'Adam':'Chicago', 'Gender':'Male', 'Location':'Chicago', 'Team':'Bears'},
{'Brandon':'Miami', 'Gender':'Male', 'Location':'Miami', 'Team':'Dolphins'} }
It easy enough to assign two starting values to get something like
{ s[0]:s[1] for s in demo}
but is there a legitimate way to assign multiple values in this comprehension that may look like
{ s[0]:s[1],'Gender':s[2], 'Team':s[3] for s in demo}
Its such a specific question and the I dont know the terms for searching so Im having a hard time finding it and the above example is giving me a syntax error.
Dictionary comprehensions build single dictionaries, not lists of dictionaries. You say you want to make a list of dictionaries, so use a list comprehension to do that.
modified_demo = [{s[0]:s[1],'Gender':s[2], 'Team':s[3]} for s in demo]
You can use zip to turn each entry into a list of key-value pairs:
dicts= [dict(zip(('Name','Gender','Location', 'Team'), data) for data in demo]
You don't want a 'Name' label, you want to use the name as a label which duplicates location. So, now you need to fix up the dicts:
for d in dicts:
d[d['Name']] = d['Location']
del d['Name'] # or not, if you can tolerate the extra key
Alternatively, you can do this in one step:
dicts = [{name:location,'Location':location,'Gender':gender, 'Team':team} for name,location,gender,team in demo]
Your requirement just looks odd, are you sure you aren't trying to logically name the fields (which makes far more sense):
>>> demo = [['Adam', 'Chicago', 'Male', 'Bears'], ['Brandon', 'Miami', 'Male', 'Dolphins']]
>>> [dict(zip(['name', 'location', 'gender', 'team'], el)) for el in demo]
[{'gender': 'Male', 'team': 'Bears', 'name': 'Adam', 'location': 'Chicago'}, {'gender': 'Male', 'team': 'Dolphins', 'name': 'Brandon', 'location': 'Miami'}]
I'm pretty new to Python, so I'm having a hard time even coming up with the proper jargon to describe my issue.
Basic idea is I have a dict that has the following structure:
myDict =
"SomeMetric":{
"day":[
{"date": "2013-01-01","value": 1234},
{"date": "2013-01-02","value": 5678},
etc...
I want to pull out the "value" where the date is known. So I want:
myDict["SomeMetric"]["day"]["value"] where myDict["SomeMetric"]["day"]["date"] = "2013-01-02"
Is there a nice one-line method for this without iterating through the whole dict as my dict is much larger, and I'm already iterating through it, so I'd rather not do nested iteritems.
Generator expressions to the resque:
next(d['value']
for d in myDict['SomeMetric']['day']
if d['date'] == "2013-01-02")
So, loop over all day dictionaries, and find the first one that matches the date you are looking for. This loop stops as soon as a match is found.
Do you have control over your data structure? It seems to be constructed in such a way that lends itself to sub-optimal lookups.
I'd structure it as such:
data = { 'metrics': { '2013-01-02': 1234, '2013-01-01': 4321 } }
And then your lookup is simply:
data['metrics']['2013-01-02']
Can you change the structure? If you can, you might find it much easier to change the day list to a dictionary which has dates as keys and values as values, so
myDict = {
"SomeMetric":{
"day":{
"2013-01-01": 1234,
"2013-01-02": 5678,
etc...
Then you can just index into it directly with
myDict["SomeMetric"]["day"]["2013-01-02"]
Here is my problem: I have a list of Python dictionaries of identical form, that are meant to represent the rows of a table in a database, something like this:
[ {'ID': 1,
'NAME': 'Joe',
'CLASS': '8th',
... },
{'ID': 1,
'NAME': 'Joe',
'CLASS': '11th',
... },
...]
I have already written a function to get the unique values for a particular field in this list of dictionaries, which was trivial. That function implements something like:
select distinct NAME from ...
However, I want to be able to get the list of multiple unique fields, similar to:
select distinct NAME, CLASS from ...
Which I am finding to be non-trivial. Is there an algorithm or Python included function to help me with this quandry?
Before you suggest loading the CSV files into a SQLite table or something similar, that is not an option for the environment I'm in, and trust me, that was my first thought.
If you want it as a generator:
def select_distinct(dictionaries, keys):
seen = set()
for d in dictionaries:
v = tuple(d[k] for k in keys)
if v in seen: continue
yield v
seen.add(v)
if you want the result in some other form (e.g., a list instead of a generator) it's not hard to alter this (e.g., .append to the initially-empty result list instead of yielding, and return the result list at the end).
To be called, of course, as
for values_tuple in select_distinct(thedicts, ('NAME', 'CLASS')):
...
or the like.
distinct_list = list(set([(d['NAME'], d['CLASS']) for d in row_list]))
where row_list is the list of dicts you have
One can implement the task using hashing. Just hash the content of rows that appear in the distinct query and ignore the ones with same hash.