I've been all over looking for a solution to this recently, and so far to no avail. I'm coming from php to python, and running into an associative array difference I'm not sure now to overcome.
Take this line:
data[user]={i:{'item':row[0],'time':row[1]}}
This overwrites each of my data[user] entries, obviously, as it's not appending, it's just replacing the data each time.
In php if I wanted to append a new bit of data in a for loop, I could do
data[user][i][]=array('item'=>'x','time'=>'y'); // crude example
In python, I can't do:
data[user][]={i:{'item':row[0],'time':row[1]}}
It barfs on my []
I also can't do:
data[user][i]={'item':row[0],'time':row[1]}
where I is my iterator through the loop... and I think it's because the data[user] hasn't been defined, yet, as of the operating? I've created the data={}, but I don't have it populated with the users as keys, yet.
In python, do I have to have a key defined before I can define it including a sub-key?
I've tried a bunch of .append() options, and other weird tricks, but I want to know the correct method of doing this.
I can do:
data[user,i]={'item':row[0],'time':row[1]}
but this isn't what I want.
What's my proper method here, python friends?
Something like this should work. Note that unlike PHP, Python has separate primitive types for numeric arrays (called "lists") and associative arrays (called "dictionaries" or "dicts").
if user not in data:
data[user] = []
data[user].append({'item': row[0], 'time': row[1]})
import collections
data = collections.defaultdict(list)
for user,row,time in input:
data[user].append({'row':row, 'time':time})
You can also use setdefault() and do something like:
userData = data.setdefault(user, {})
userData[i] = {'item': row[0], 'time': row[1]}
If data[user] is a list, you can append to it with data[user].append({'item':row[0],'time':row[1]}).
Related
When trying to iterate through a defaultdict my variables were read as strings when they should be read as lists, however, when I changed my code a little bit, it worked but I don't know exactly why. My defaultdict is a dictonary that has a list of dictionaries inside it. The code looked like that
for engagement in engagement_by_account:
for engagement in engagement:
engagement['total_minutes_visited'] = float(engagement['total_minutes_visited'])
And the error was:
TypeError: string indices must be integers
However, when I changed the code to this:
for key,engagement in engagement_by_account.items():
for engagement in engagement:
engagement['total_minutes_visited'] = float(engagement['total_minutes_visited'])
there were no errors anymore.
By default, when you iterate over a dictionary (or defaultdict), you will iterate over the keys of that dictionary. It seems here that you wanted to iterate over the values so you could either do what you did or something like:
for engagements in engagement_by_account.values():
for engagement in engagements:
engagement['total_minutes_visited'] = float(engagement['total_minutes_visited'])
Similar to this question: Tuple declaration in Python
I have this function:
def get_mouse():
# Get: x:4631 y:506 screen:0 window:63557060
mouse = os.popen( "xdotool getmouselocation" ).read().splitlines()
print mouse
return mouse
When I run it it prints:
['x:2403 y:368 screen:0 window:60817757']
I can split the line and create 4 separate fields in a list but from Python code examples I've seen I feel there is a better way of doing it. I'm thinking something like x:= or window:=, etc.
I'm not sure how to properly define these "named tuple fields" nor how to reference them in subsequent commands?
I'd like to read more on the whole subject if there is a reference link handy.
It seems it would be a better option to use a dictionary here. Dictionaries allow you to set a key, and a value associated to that key. This way you can call a key such as dictionary['x'] and get the corresponding value from the dictionary (if it exists!)
data = ['x:2403 y:368 screen:0 window:60817757'] #Your return data seems to be stored as a list
result = dict(d.split(':') for d in data[0].split())
result['x']
#'2403'
result['window']
#'60817757'
You can read more on a few things here such as;
Comprehensions
Dictionaries
Happy learning!
try
dict(mouse.split(':') for el in mouse
This should give you a dict (rather than tuples, though dicts are mutable and also required hashability of keys)
{x: 2403, y:368, ...}
Also the splitlines is probably not needed, as you are only reading one line. You could do something like:
mouse = [os.popen( "xdotool getmouselocation" ).read()]
Though I don't know what xdotool getmouselocation does or if it could ever return multiple lines.
I'm relatively new to python and programing and have code that is working, however I'd like to know if there is a better more condensed way to achieve the same thing.
My code creates a dictionary with some context key value pairs, then I go and get groups of questions looping a number of times. I want to gather all the questions into my data dictionary, adding the list of questions the first time, and extending it with subsequent loops.
My working code:
data = {
'name': product_name,
'question summary': question_summary,
}
for l in loop:
<my code gets a list of new questions>
if 'questions' not in data:
data ['questions'] = new_questions['questions']
else:
all_questions = data.get('questions')
all_questions.extend(new_questions['questions'])
data ['questions'] = all_questions
I've read about using a default dict to enable automatic creation of a dictionary item if it doesn't exist, however I'm not sure how I would define data in the first place as some of its key value pairs aren't lists and I want it to have the extra context key value pairs.
I also feel that the 3 lines of code appending more questions to the list of questions in data (if it exists) should/could be shorter but this doesn't work as data.get() isn't callable
data['questions'] = data.get('questions').extend(new_questions['questions'])
and this doesn't work because extend returns none:
data['questions'] = all_questions.extend(new_questions['questions'])
Ok so I figured out how to condense the 3 lines, see answer, below however I'd still like to know if the If: else: is good form in this case.
You might be looking for the setdefault method:
data.setdefault('questions', []).extend(new_questions['questions'])
Ok so Quack Quack I figured out how to condense the 3 lines - this works:
data['questions'].extend(new_questions['questions'])
I am new to data structures in python and was wondering how do you simulate a thing like pointers in python so that multiple structures can refer and manage the same piece of data.
I have the following two structures
my_list = [1]
my_dictionary = {}
my_dictionary["hello"] = my_list[0]
and when I do the following I get True
id(my_dictionary["hello"]) == my_list[0]
However how can I force removal both from the dict and the list in one go?
If I do the following my_dictionary still has a reference to my_list[0] i.e. 1
del my_list[0]
is there a way to get rid of both of these elements in one go? What is the python way of doing linked structures like this?
It really depends on the point you're trying to solve by cross-referencing.
Suppose your intent is to be able to efficiently both locate an item by key, as well as to sequentially iterate by order. In this case, irrespective of the language, you probably would wish to avoid cross referencing a hash-table and an array data structures, as the updates are inherently linear. Conversely, cross referencing a hash-table and a list might make more sense.
For this, you can use something like llist:
d = {}
l = llist.dllist()
# insert 'foo' and obtain the link
lnk = l.append('foo')
# insert the link to the dictionary
d['foo'] = lnk
Conversely, suppose your intent is to be able to efficiently both locate an item by key, as well as to locate by index. Then you can use a dict and a list, and rebuild the list on each modification of the dict. There is no real reason for fancy cross-referencing.
Simply put, there is no way to easily link your two structures.
You could manipulate the object you point to so that it has some "deleted" state and would act as if it's deleted (while being in both containers).
However, if all you wanted was a list from a dict, use list(the_dict.values()).
You could make a class to achieve this, if all else fails. See https://docs.python.org/2/reference/datamodel.html#emulating-container-types for the details on what your class would have to have. Within the class, you would have your "duplicated effort," but if it's correctly implemented it wouldn't be error prone.
You can always do things like this:
Pointers in Python?
(a quick stackoverflow search shows some results)
But that is messing with more than just data structures.
Remember that Python manages memory for you (in most of the cases, pretty well), so you don't have to worry of cleaning after yourself.
i have tried the following peice of code and it works (changing in one DataStructure changes for the other).
does this help?
list1 = [1,2,3]
list2 = [4,5,6]
my_dictionary = {}
my_dictionary["a"] = list1
my_dictionary["b"] = list2
del list1[0]
print list1
print list2
print my_dictionary
I couldn't find a guide that would help me out in this area. So I was hoping somebody could help me explain this kind of programming in Python. I am trying to write a code that goes something like this:
def Runner():
for G in range(someRange):
makeListObjectcalled 'ListNumber'+'G'
ListNumberg.append(G*500000 or whatever)
print ListNumberG
#so I would have a someRange amount of lists
#named 0,1,2,3...(up to someRange) I could look through
I think it can be done with classes (in fact I'm guessing thats what they're for...) but I'm not sure. Could someone lay me down some clarifications please?
It looks like what you really want is a list of lists.
def Runner():
Lists = []
for G in range(someRange):
Lists[G] = []
Lists[G].append(G*500000 or whatever)
print Lists[G]
#This way, you have Lists[0], Lists[1], ..., Lists[someRange]
You want to dynamically create variables of type lists that store an array of values.
An easier and better approach (than juggling unknown variable names) is to use a dictionary to keep your lists in, so you can look them up by name/key:
(pseudo code, don't have my Python interpreter with me)
# create a dictionary to store your ListNumberG's
dict_of_lists = {}
# down the line in your loop, add each generated list to the dict:
dict_of_lists['ListNumberG'] = ListNumberG
Later you can find a list by it's name/key via
print(dict_of_lists['ListNumberG'])
or loop through them
for idx in range(bestguess):
print(dict_of_lists['ListNumber%s' % (idx,)])