This question already has an answer here:
How do I remove words from a List in a case-insensitive manner?
(1 answer)
Closed 4 years ago.
is there a way in Python to remove all matches of a name, but make it case insensitive, similar to: myArray.remove("john") ? i want to remove all instances of John and john from the array without having to write out a loop
You can't use remove for this, but you can easily write your own function that does it manually.
For example:
def remove_ci(lst, s):
s = s.casefold()
for i, elem in enumerate(lst):
if elem.casefold() == s:
del lst[i]
return
raise ValueError('remove_ci(x): x not in list')
Or, if you'd rather do it by copying rather than in-place mutation:
def removed_ci(iterable, s):
s = s.casefold()
for elem in iterable:
if elem.casefold() == s:
yield from iterable
return
yield elem
raise ValueError('removed_ci(x): x not in iterable')
(You can make the second version a lot more concise with itertools.takewhile, but probably better to write out the loops and comparisons explicitly the first time you need to do something like this.)
Your question says you "want to remove all instances of…" But that's not what list.remove does; it removes only the first instance, and it raises an exception if there are no instances.
Related
This question already has answers here:
fit "break IF condition" statement into one line
(3 answers)
Closed 4 months ago.
I'm looking for options of shortening syntax for breaking (and continuing) a loop on a condition
for _ in range(10):
if condition:
break
...
I supposed that short curcuits should work, e.g. x == 2 and break, but they cause SyntaxError.
What are Python's options for one-line conditioning, except if condition: break?
You could use itertools.takewhile to combine aspects of a for and while loop, moving the (negated) break condition to the loop's head. The condition in the lambda can use both variables from the enclosing scope and the current item from the iterable.
from itertools import takewhile
for x in takewhile(lambda x: not condition, iterable):
...
However, while this is shorter (at least in terms of lines), I would not consider it more readable. I would just stick with the explicit break.
This question already has answers here:
How can I get a reversed copy of a list (avoid a separate statement when chaining a method after .reverse)?
(11 answers)
Python a = a.reverse makes the list empty?
(7 answers)
Closed 1 year ago.
Here is the question I am trying to answer:
Write code that accepts a list of strings as its parameter and indicates whether that list is a palindrome. A palindrome list is one that reads the same forward as backward. For example, the list ["alpha", "beta", "gamma", "delta", "gamma", "beta", "alpha"] is a palindrome.
def palindrome_checker(list):
if list == list.reverse():
print('Palindrome')
else:
print('Not Palindrome')
user_list = []
user_input = (input('Enter list of words'))
user_list = [user_input.split()]
palindrome_checker(user_list)
My code responds "Not Palindrome" no matter what. Can anyone tell me what I am missing?w
list.reverse() does not return the reversed version of the list, it actually doesn't return anything at all. The reverse function actually changes the original list object.
So basically, you're saying if list == None in that statement.
Does that make sense?
You can generally assume anytime you call a method that belongs to an object, for example in this case, the reverse() method in the List object, that the method is going to change the original object, not return a new value.
What you want is:
reversedList = list(reversed(original_list))
if original_list = reversed_list:
On another note, I suggest you rename your parameter from list to something else for the sake of cleanliness. You want to avoid namespace collisions since the word list already refers to the type list and the method list that constructs a list.
For fun a variation on #bdbd answer:
def palindrome_checker(l):
return ('' if l == list(reversed(l)) else 'Not ') + 'Palindrome'
Aside from the answers already here, you can also do:
my_list == list(reversed(my_list))
or
list == list[::-1]
EDIT:
First one will fail because of conflicting names on list, since it's a reserved keyword built-in function. I suggest change the name of your variable as well to something different if you choose the first approach
reverse is an inplace function i.e it returns None. So a list is never equal to None. Also, .split() itself provides a list. [user_input.split()] will create a nested list.
So a solution.
Remove the [] from .split()
Create a copy of the list before you reverse it.
def palindrome_checker(lists):
lists2=lists[:]
lists.reverse()
if lists2 == lists:
print('Palindrome')
else:
print('Not Palindrome')
user_list = []
user_input = (input('Enter list of words'))
user_list = user_input.split()
palindrome_checker(user_list)
This question already has answers here:
How to reuse an expression in a comprehension expression?
(2 answers)
Closed 2 years ago.
I have a code that looks like this:
x = ["hello","world","if"]
test = [len(word) for word in x if len(word)>4]
print(test)
in my original code "len" is much complicated function, is there a way to do the calcualtion of len only once?
in a traditional for loop it can be done like this:
test = []
for word in x:
temp= len(word)
if temp > 4:
test.append(temp)
can you please advise how to achieve the same result without using a traditional for loop.
Thanks
You can use := operator (in case of Python 3.8+):
def my_len(s):
# ...other complicated computations...
return len(s)
x = ["hello","world","if"]
test = [l for word in x if (l:=my_len(word))>4]
print(test)
Note: don't overwrite default built-in functions, in this case len(). Other functions may depend on it.
This question already has answers here:
Find first sequence item that matches a criterion [duplicate]
(2 answers)
Closed 7 years ago.
Is there a built in function in Python that will return a single result given a list and a validation function?
For example I know I can do the following:
resource = list(filter(lambda x: x.uri == uri, subject.resources))[0]
The above will extract a resource from a list of resources, based on ther resource.uri field. Although this field value is uinique, so I know that I will either have 1 or 0 results. filter function will iterate the whole list. In my case its 20 elements, but I want to know if there is some other built-in way to stop the iteration on first match.
See https://docs.python.org/3/library/functions.html#next
next(iterator[, default])
Retrieve the next item from the iterator by calling its next() method. If default is given, it is returned if the iterator is exhausted, otherwise StopIteration is raised.
e.g. in your case:
resource = next(filter(lambda x: x.uri == uri, subject.resources), None)
This question already has answers here:
Flatten an irregular (arbitrarily nested) list of lists
(51 answers)
Closed 6 months ago.
I asked a while ago about how to make a list of sublists (and of even more sublists) from a string given delimiters here.
How to process a string into layer of sublists
Now, I need to join them back together and I'm not sure how. I have tried to look here
Python : Recursively flatten a list
and
Flatten a list in python
However, neither of these answers work in my case because chain splits my string (single item "lists") into characters, and then therefore cannot join with "\n", and reduce does not concatenate str and list objects.
I will probably need to walk through the sublists (and their sublists) at some point. Is there a way to iterate through each level of sublist? (I can leave this as a separate question, one step at a time.. but just wondering whether this process is making sense or should I try an entire new method. I do think logically this makes the most sense, I'm just having trouble navigating it.)
Thanks.
I'm going to assume what I said in the comment is correct unless you say otherwise.
From the posts you linked, you have:
import collections
def flatten(l):
for el in l:
if isinstance(el, collections.Iterable) and not isinstance(el, basestring):
for sub in flatten(el):
yield sub
else:
yield el
to recursively flatten an irregular list of lists, and
def go(it):
for x in it:
if x == 'b':
yield [x] + list(go(it))
else:
yield x
if x == 'c':
break
to create that irregular list of lists from an iterator.
The inverse of go is just flatten(output_of_go) so the inverse of go(iter(string)) is ''.join(flatten(output_of_go)). You can see that with this test code:
lst = "aaabaabacabaacaca"
assert ''.join(flatten(go(iter(lst)))) == lst