I have a list of n strings. For example, strings = ('path1','path2',path3')
I want to create n variables that are equal to functions on these strings. For example:
s1=pygame.mixer.Sound('path1')
s2=pygame.mixer.Sound('path2')
s3=pygame.mixer.Sound('path3')`
I've looked this up a few times before and answers always seem to refer to dictionaries. I am not too familiar with dictionaries although I know their basic function. I don't know how I would use a dictionary to accomplish this.
The problem with dynamically creating variables is: how do you plan on referring them in your code? You'll need to have some abstracted mechanism for dealing with 0..n objects, so you might as well store them in a data type that can deal with collections. How you store them depends on what you want to do with them. The two most obvious choices are list and dict.
Generally, you'll use a list if you want to deal with them sequentially:
paths = ['path1', 'path2', 'path3']
sounds = [ pygame.mixer.Sound(path) for path in paths ]
# play all sounds sequentially
for sound in sounds:
sound.play()
Whereas dict is used if you have some identifier you want to use to refer to the items:
paths = ['path1', 'path2', 'path3']
sounds = { path: pygame.mixer.Sound(path) for path in paths }
# play a specific sound
sounds[name].play()
You don't need to use a dictionary. Use map.
s = map(pygame.mixer.Sound, strings)
The above statement will call pygame.mixer.Sound with each of the strings in strings as arguments, and return the results as a list. Then you can access the variables like you would access any item from a list.
s1 = s[0] # based on your previous definition
The idea is you use a dictionary (or a list) instead of doing that. The simplest way is with a list:
sounds = [pygame.mixer.Sound(path) for path in strings]
You then access them as sounds[0], sounds[1], sounds[2], etc.
Related
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 have a list that should contain all my other lists. Currently I append every list separately but that just looks pretty ugly..
looplist = [] # initiate an empty list that contains all date from the other lists
[...]
looplist.append(internallist1)
[...]
looplist.append(internallist10)
the internallists are all getting initialized and filled in a for loop
You can simply use + to merge them.
You may check for more info.
If you want to have list of lists, check this topic.
listOne.extend(anotherList)
this could help you: https://docs.python.org/3/tutorial/datastructures.html
you can also do listOne+=anotherList and this is less expensive, as it doesn`t involve a function call like extend
To answer what you are asking, Just initialize looplist with your 10 lists.
looplist = [internallist1,
internallist2,
internallist3] #Note: internallist3,] is also valid, python allows trailing comma. Nifty!
However, your 10 lists really shouldn't be separately named lists in the first place if this is your real use case. Just use looplist[0] through looplist[9] instead from the get go.
The zip method could work for you as you stated your output should:
look something like [ [list1], [list2], ... , [list n] ]
in your case the code would be similar to
looplist = list(zip(internallist1,[...], internallist10))
In python, Suppose I have a list:
instruments = ['apd', 'dd', 'dow', 'ecl']
How can I split these lists so that it will create:
apd[]
dd[]
dow[]
ecl[]
Thanks for the help.
You would do this:
dictionaries = {i:[] for i in instruments}
and you you would refer to each list this way:
dictionaries['apd']
dictionaries['dd']
dictionaries['dow']
dictionaries['ecl']
This is considered much better practice than actually having the lists in the current namespace, as it would both be polluting and unpythonic.
mshsayem has the method to place the lists in the current scope, but the question is, what benefits do you get from putting them in your current scope?
Standard use cases:
you already know the names of the items, and want to refer to them directly by name, i.e. apd.append
you don't know the names yet, but you'll use eval or locals to get the lists, i.e. eval('apd').append or locals()['apd'].append
Both can be satisfied using dictionaries:
dictionaries['<some name can be set programatically or using a constant>'].append
Try this:
instruments = ['apd', 'dd', 'dow', 'ecl']
l_dict = locals()
for i in instruments:
l_dict[i] = []
This will create apd,dd,dow,ecl lists in the local scope.
Snakes and Cofee's idea is better though.
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,)])
Is there a better way to implement a paging solution using dict than this?
I have a dict with image names and URLs.
I need to 16 key value pairs at a time depending on the user's request, i.e. page number.
It's a kind of paging solution.
I can implement this like:
For example :
dict = {'g1':'first', 'g2':'second', ... }
Now I can create a mapping of the keys to numbers using:
ordered={}
for i, j in enumerate(dict):
ordered[i]=j
And then retrieve them:
dicttosent={}
for i in range(paegnumber, pagenumber+16):
dicttosent[ordered[i]] = dict[ordered[i]]
Is this a proper method, or will this give random results?
Store g1, g2, etc in a list called imagelist
Fetch the pages using imagelist[pagenumber: pagenumber+16].
Use your original dict (image numbers to urls) to lookup the url for each of those 16 imagenames.
1) Will this give random results ?
Sort of.
Quoting from the official documentation about dict:
Keys and values are iterated over in an arbitrary order which is non-random, varies across Python implementations, and depends on the dictionary’s history of insertions and deletions.
So for your purposes you can't know a priori on what will be the order of your iteration.
OrderedDict is what you're looking for: an OrderedDict is a dict that remembers the order that keys were first inserted.
2) Is this actually a proper method?
It doesn't seem so.
I don't know if there are library that will handle all that information for you (maybe someone else can tell you that), but it seems like you're trying to emulate the OrderedDict behaviour.
You can directly use an OrderedDict, or if you want to enumerate your info a list can do that.
It depends. If your dict doesn't change during the lifetime of the application and you don't care about ordering of the items in your dict you should be ok.
If not, you should probably use collections.OrderedDict or keep a sorted list of keys, depending on your requirements. Using normal dict doesn't give you any guarantees about iteration order, so after each modification of the input dict you can get different results.
Why not just create a dict that maps to your pages? You could start off with two lists, one containing your image names and the other containing the URLs.
perPage = 16
nameList = ['g1', 'g2', ... ]
urlList = ['first', 'second', ... ]
# This is a generator expression that can create
# the nested dicts. You can also use a simple
# for loop
pageDict = dict(( (i, dict(( (nameList[j], urlList[j])
for j in range(i*perPage, i*perPage+perPage))))
for i in range(len(nameList) / perPage)))
It indexes from 0, so your first page will be pageDict[0].
...Now that I look at it again, that generator expression looks kind of awful. :|