Check if item is in an array / list [duplicate] - python

This question already has answers here:
Is there a short contains function for lists?
(6 answers)
Closed last month.
If I've got an array of strings, can I check to see if a string is in the array without doing a for loop? Specifically, I'm looking for a way to do it within an if statement, so something like this:
if [check that item is in array]:

Assuming you mean "list" where you say "array", you can do
if item in my_list:
# whatever
This works for any collection, not just for lists. For dictionaries, it checks whether the given key is present in the dictionary.

I'm also going to assume that you mean "list" when you say "array." Sven Marnach's solution is good. If you are going to be doing repeated checks on the list, then it might be worth converting it to a set or frozenset, which can be faster for each check. Assuming your list of strs is called subjects:
subject_set = frozenset(subjects)
if query in subject_set:
# whatever

Use a lambda function.
Let's say you have an array:
nums = [0,1,5]
Check whether 5 is in nums in Python 3.X:
(len(list(filter (lambda x : x == 5, nums))) > 0)
Check whether 5 is in nums in Python 2.7:
(len(filter (lambda x : x == 5, nums)) > 0)
This solution is more robust. You can now check whether any number satisfying a certain condition is in your array nums.
For example, check whether any number that is greater than or equal to 5 exists in nums:
(len(filter (lambda x : x >= 5, nums)) > 0)

You have to use .values for arrays.
for example say you have dataframe which has a column name ie, test['Name'], you can do
if name in test['Name'].values :
print(name)
for a normal list you dont have to use .values

You can also use the same syntax for an array. For example, searching within a Pandas series:
ser = pd.Series(['some', 'strings', 'to', 'query'])
if item in ser.values:
# do stuff

Related

How to get into details of str() and int() conversion [duplicate]

Tackling a few puzzle problems on a quiet Saturday night (wooohoo... not) and am struggling with sort(). The results aren't quite what I expect. The program iterates through every combination from 100 - 999 and checks if the product is a palindome. If it is, append to the list. I need the list sorted :D Here's my program:
list = [] #list of numbers
for x in xrange(100,1000): #loops for first value of combination
for y in xrange(x,1000): #and 2nd value
mult = x*y
reversed = str(mult)[::-1] #reverses the number
if (reversed == str(mult)):
list.append(reversed)
list.sort()
print list[:10]
which nets:
['101101', '10201', '102201', '102201', '105501', '105501', '106601', '108801',
'108801', '110011']
Clearly index 0 is larger then 1. Any idea what's going on? I have a feeling it's got something to do with trailing/leading zeroes, but I had a quick look and I can't see the problem.
Bonus points if you know where the puzzle comes from :P
You are sorting strings, not numbers. '101101' < '10201' because '1' < '2'. Change list.append(reversed) to list.append(int(reversed)) and it will work (or use a different sorting function).
Sort is doing its job. If you intended to store integers in the list, take Lukáš advice. You can also tell sort how to sort, for example by making ints:
list.sort(key=int)
the key parameter takes a function that calculates an item to take the list object's place in all comparisons. An integer will compare numerically as you expect.
(By the way, list is a really bad variable name, as you override the builtin list() type!)
Your list contains strings so it is sorting them alphabetically - try converting the list to integers and then do the sort.
You're sorting strings, not numbers. Strings compare left-to-right.
No need to convert to int. mult already is an int and as you have checked it is a palindrome it will look the same as reversed, so just:
list.append(mult)
You have your numbers stored as strings, so python is sorting them accordingly. So: '101x' comes before '102x' (the same way that 'abcd' will come before 'az').
No, it is sorting properly, just that it is sorting lexographically and you want numeric sorting... so remove the "str()"
The comparator operator is treating your input as strings instead of integers. In string comparsion 2 as the 3rd letter is lexically greater than 1.
reversed = str(mult)[::-1]

Find next available integer in sorted list [duplicate]

This question already has answers here:
How to find a missing number from a list?
(18 answers)
Closed 1 year ago.
I have a sorted list of integers:
l = [1,2,4,5]
I want to find the next free number in that range, in this case 3.
Are there available Python functions that can help with this? To create this manually I was thinking I would need to fetch the first and last index from l and create a new list, l_all, of all sequential integers inbetween those two values. Then walk and compare both lists and when a number exists in l_all but does not exist in l I would have my next free number. I'm curious if there is a more Pythonic way of doing this.
The suggested duplicate appears to be looking for a single missing value, but your case asks for the first available integer.
This can be done in a single line without a loop:
l = [1,2,4,5]
min(set(range(1, max(l)+1)) - set(l))
3
This is performing a set difference between a set of all possible integers from 1 to the max value in your list, set(range(1, max(l)+1)), and the set of values in your list, set(l). Sets are unsorted by nature, so you can use the min of the resulting set to find the first missing integer.
One advantage of using sets over lists to find the missing values is that it will still work without sorting your initial list, whereas any method involving looping across values will require the initial list to be sorted.
Also FYI, set(a) - set(b) could also be written as set(a).difference(set(b)). Both are functionally equivalent.
for i in range(len(l)):
a, b = i, i+1
if b < len(l):
if l[b] - l[a] > 1:
print(l[a] + 1)

Skip over a set of values (in an array) in a loop - Python3 [duplicate]

This question already has answers here:
Comparing a string to multiple items in Python [duplicate]
(3 answers)
Closed 8 months ago.
I have a loop to read in data, but the numbering isn't continuous. Thus, I want to skip specific values. But I only knew how to skip one, not a set of values.
This is my example code:
for n in [x for x in range(2,m) if x!=9]:
if n < 10:
stationsnr = '00'+np.str(n)
elif n < 100:
stationsnr = '0'+np.str(n)
else:
stationsnr = np.str(n)
But instead of "x!=9" I need something like if x!= one of those values [9,10,12,16,......] (edit: the values are stored in a list). Any suggestions?
You can test if the value is a member of a set:
[... if x not in {9, 10, 12, 16, }]
Set membership testing is O(1) constant time (so fast!).
You can use the enumerate() function in your for loop. It returns the element of the list like normal, but also returns the index position. For example:
indices_to_avoid = [1,4,6] # indices to skip over
for item, idx in enumerate(range(2, m)):
if idx not in indices_to_avoid:
do_something()
Like the above answers said, you can also use a list comprehension, but if you have a long list of exclusions, the list comprehension can get lengthy. I think lengthy list comprehensions are difficult to read and can confuse more than a simple for loop, especially if the list comp goes onto the next line.
You could use -
if x is not in [your list]
But it'd be better to use a set than a list because the look-up time on sets is O(1), which is constant, since they're hashed.
So your code could become -
if x is not in (your set)
Also, the append time for list is O(N) while for set is O(1) so inserting to a set will also be faster (and removing from it too)

Create a new list with changes of value of a previous list

I have a list with floats, for example
numbers = [1000.45,1002.98,1005.099,1007.987]
I want to create a new list containing the deltas of the value in numbers - i.e. I want the difference between numbers[0],[numbers[1] to be the first value in a new list. So the first number in my new list should be 2.53, the second should be 2.119, and so forth.
I tried list comprehension
newnumbers= [i[-1] - i[-2] for i in numbers]
but it gives a TypeError
TypeError: 'float' object is not subscriptable
I tried converting the list to integers, but then it gives the same type of error.
How can I create my desired list?
It's easy with Pandas, use diff():
import pandas as pd
pd.Series(numbers).diff()
0 NaN
1 2.530
2 2.119
3 2.888
dtype: float64
You've got the right idea, but just haven't quite got the syntax right. You should use:
newnumbers = [(numbers[i] - numbers[i-1]) for i in range(1, len(numbers))]
In your version you're trying to index a number, but you need to index your list instead.
newnumbers = []
for i in range(1,len(numbers)-1):
newnumbers.append(numbers[i]-numbers[i-1])
for i in numbers i is equal to 1000.45 in the first loop, then 1002.98 etc. So i[-1] = 1000.45[-1] which means nothing, you cannot subscriptable a float
numbers = [1000.45,1002.98,1005.099,1007.987]
newnumbers= [numbers[i+1]-numbers[i] for i in range(len(numbers)-1)]
print(newnumbers)
#[2.5299999999999727, 2.119000000000028, 2.88799999999992]
If you want 2 decimal points
newnumbers= [float("%0.2f"%(numbers[i+1]-numbers[i])) for i in range(len(numbers)-1)]
#[2.53, 2.12, 2.89]
Note how you access your elements directly, instead of using list indices;
The correct way to do the latter in Python would be
for index in range(len(numbers)):
What you are using is essentially the numbers themselves. Also, note that you would have to exclude the first index of your list, since you only want the differences (otherwise, the first call would look at the last index again, according to Python's behavior of calling mylist[-1]), which is why you can restrict your range to range(1,len(numbers)). In the form of a list comprehension, it would now work like this:
newnumbers = [numbers[i] - numbers[i-1] for i in range(1,len(numbers))]
Here is a method that doesn't require importing any modules:
numbers = [1000.45,1002.98,1005.099,1007.987]
sliced = numbers[1:]
answer = list(map((lambda x,y: y - x),sliced,numbers))
This gives:
[-2.5299999999999727, -2.119000000000028, -2.88799999999992]
You can then do:
final_answer = [round(x,2) for x in answer]
which gives:
[-2.53, -2.12, -2.89]
>>> numbers = [1000.45,1002.98,1005.099,1007.987]
>>> [round((y-x),2) for x,y in zip(numbers, numbers[1:])]
[2.53, 2.12, 2.89]

Python .sort() not working as expected

Tackling a few puzzle problems on a quiet Saturday night (wooohoo... not) and am struggling with sort(). The results aren't quite what I expect. The program iterates through every combination from 100 - 999 and checks if the product is a palindome. If it is, append to the list. I need the list sorted :D Here's my program:
list = [] #list of numbers
for x in xrange(100,1000): #loops for first value of combination
for y in xrange(x,1000): #and 2nd value
mult = x*y
reversed = str(mult)[::-1] #reverses the number
if (reversed == str(mult)):
list.append(reversed)
list.sort()
print list[:10]
which nets:
['101101', '10201', '102201', '102201', '105501', '105501', '106601', '108801',
'108801', '110011']
Clearly index 0 is larger then 1. Any idea what's going on? I have a feeling it's got something to do with trailing/leading zeroes, but I had a quick look and I can't see the problem.
Bonus points if you know where the puzzle comes from :P
You are sorting strings, not numbers. '101101' < '10201' because '1' < '2'. Change list.append(reversed) to list.append(int(reversed)) and it will work (or use a different sorting function).
Sort is doing its job. If you intended to store integers in the list, take Lukáš advice. You can also tell sort how to sort, for example by making ints:
list.sort(key=int)
the key parameter takes a function that calculates an item to take the list object's place in all comparisons. An integer will compare numerically as you expect.
(By the way, list is a really bad variable name, as you override the builtin list() type!)
Your list contains strings so it is sorting them alphabetically - try converting the list to integers and then do the sort.
You're sorting strings, not numbers. Strings compare left-to-right.
No need to convert to int. mult already is an int and as you have checked it is a palindrome it will look the same as reversed, so just:
list.append(mult)
You have your numbers stored as strings, so python is sorting them accordingly. So: '101x' comes before '102x' (the same way that 'abcd' will come before 'az').
No, it is sorting properly, just that it is sorting lexographically and you want numeric sorting... so remove the "str()"
The comparator operator is treating your input as strings instead of integers. In string comparsion 2 as the 3rd letter is lexically greater than 1.
reversed = str(mult)[::-1]

Categories