How to ensure list contains unique elements? - python

I have a class containing a list of strings. Say:
ClassName:
- list_of_strings
I need to enforce that this list of strings contains unique elements. Unfortunately, I can't change this list_of_strings to another type, like a set.
In the addToList(str_to_add) function, I want to guarantee string uniqueness. How can I best do this? Would it be practical to add the string being added to the list, convert to a set, then back to a list, and then reassign that to the object?
Here's the method I need to update:
def addToList(self, str_to_add):
self.list_of_strings.append(str_to_add)
Thanks!

def addToList(self, str_to_add):
if str_to_add not in self.list_of_strings:
self.list_of_strings.append(str_to_add)

Either check for the presence of the string in the list with in, or use a set in parallel that you can check and add to.

You indeed could do the list-to-set-to-list operation you described, but you could also use the in operator to check if the element is already in the list before appending it.

One possible way to do this would be to create a hash set and iterate through the list, adding the elements to the set; a second iteration could be used to remove any duplicates.

Perhaps we can do like this:
def addToList(self, str_to_add):
try:
self.list_of_strings.index(str_to_add)
except:
self.list_of_strings.append(str_to_add)
Well, I don't know whether it's the same mechanism with if/else yet.

Related

How can I pass each element of a set to a function?

I have a set with multiple tuples: set1 = {(1,1),(2,1)} for example.
Now I want to pass each tuple of the set to a method with this signature: process_tuple(self, tuple).
I am doing it with a for loop like this:
for tuple in set1:
process_tuple(tuple)
Is there a better way to do it?
Your question is basically "how can I loop without using a loop". While it's possible to do what you're asking with out an explicit for loop, the loop is by far the clearest and best way to go.
There are some alternatives, but mostly they're just changing how the loop looks, not preventing it in the first place. If you want to collect the return values from the calls to your function in a list, you can use a list comprehension to build the list at the same time as you loop:
results = [process_tuple(tuple) for tuple in set1]
You can also do set or dict comprehensions if those seem useful to your specific needs. For example, you could build a dictionary mapping from the tuples in your set to their processed results with:
results_dict = {tuple: process_tuple(tuple) for tuple in set1}
If you don't want to write out for tuple in set1 at all, you could use the builtin map function to do the looping and passing of values for you. It returns an iterator, which you'll need to fully consume to run the function over the full input. Passing the map object to list sometimes makes sense, for instance, to convert inputs into numbers:
user_numbers = list(map(int, input("Enter space-separated integers: ").split()))
But I'd also strongly encourage you to think of your current code as perhaps the best solution. Just because you can change it to something else, doesn't mean you should.

python: how to append multiple lists to one

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))

Variable Variables in Python

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.

Check if string doesn't exist in List

I have a List of Strings in Python and I want to check if the string "EVN" does not exist in the range segmentList[x][0:3], so I can create it in a specific place in the list.
I'm trying to check if the string in this range (segmentType = segmentList[x][0:3]) in the list and if it doesn't I want to call a method create_EVN() and insert the "EVN" string into the second position of the list moving up the other elements rather that deleting them.
I'm fairly new to python and I'm trying to find the most efficient way possible to do this. I have tried looping through the list with no avail.
Is this what you are looking for?
if 'EVN' not in segmentList[x][0:3]:
create_EVN()
How about
if 'EVN' not in segmentList[x][0:3] :
create_EVN()

Need to understand function in python

def process_filter_description(filter, images, ial):
'''Return a new list containing only items from list images that pass
the description filter (a str). ial is the related image association list.
Matching is done in a case insensitive manner.
'''
images = []
for items in ial:
Those are the only two lines of code I have so far. What is troubling me is the filter in the function. I really don't know what the filter is supposed to do or how to use it.
In no way am I asking for the full code. I just want help with what the filter is supposed to do and how I can use it.
Like I said in my comment, this is really vague. But I'll try to explain a little about the concept of a filter in python, specifically the filter() function.
The prototype of filter is: iterable <- filter(function, iterable).
iterable is something that can be iterated over. You can look up this term in the docs for a more exact explanation, but for your question, just know that a list is iterable.
function is a function that accepts a single element of the iterable you specify (in this case, an element of the list) and returns a boolean specifying whether the element should exist in the iterable that is returned. If the function returns True, the element will appear in the returned list, if False, it will not.
Here's a short example, showing how you can use the filter() function to filter out all even numbers (which I should point out, is the same as "filtering in" all odd numbers)
def is_odd(i): return i%2
l = [1,2,3,4,5] # This is a list
fl = filter(is_odd, l)
print fl # This will display [1,3,5]
You should convince yourself that is_odd works first. It will return 1 (=True) for odd numbers and 0 (=False) for even numbers.
In practice, you usually use a lambda function instead of defining a single-use top-level function, but you shouldn't worry about that, as this is just fine.
But anyway, you should be able to do something similar to accomplish your goal.
Well it says in the description line:
Return a new list containing only items from list images that pass the description filter (a str)
...
Matching is done in a case insensitive manner
So.. im guessing the filter is just a string, do you have any kind of text associated with the images ? some kind of description or name that could be matched against the filter string ?

Categories

Resources