List and Integer query - python

If i had a list of numbers and some maybe negative, how would i ensure all numbers in my list were positive? I can covert the items in the list to integers thats no problem.
Another question, I want to compare items in my list to an integer value say 'x' and sum all the values in my list that are less than x.
Thank you.

If you have a list Ns of numbers (if it's a list of strings as in several similar questions asked recently each will have to be made into an int, or whatever other kind of number, by calling int [[or float, etc]] on it), the list of their absolute values (if that's what you mean by "ensure") is
[abs(n) for n in Ns]
If you mean, instead, to check whether all numbers are >= 0, then
all(n >= 0 for n in Ns)
will give you a bool value respecting exactly that specification.
The sum of the items of the list that are <x is
sum(n for n in Ns if n < x)
Of course you may combine all these kinds of operations in one sweep (e.g. if you need to take the abs(n) as well as checking if it's < x, checking if it's >= 0, summing, whatever).

# input list is named "lst"
pos_list = [int(a) for a in lst if int(a) > 0]
# And num 2 (notice generator is used instead of list)
return sum(a for a in lst if a < x)

Answer / First part:
>>> a = [1, 2, -3, 4, 5, 6]
>>> b = [1, 2, 3, 4, 5, 6]
>>> max(map(lambda x: x < 0, a))
False
>>> max(map(lambda x: x < 0, b))
True
Or just use min:
>>> min(a) < 0
True
>>> min(b) < 0
False
Second part:
>>> x = 3
>>> sum(filter(lambda n: n < x, a))
>>> 0
>>> sum(filter(lambda n: n < x, b))
>>> 3

If I understand correctly your question, I guess you are asking because of some class about functional programming.
In this case, what you are asking for can be accomplished with functional programming tools available in Python.
In particular, the first point can be solved using filter, while the second with map and reduce (or, better, with map and sum).

>>>mylist = [1,2,3,-2]
>>>any(item for item in mylist if item < 0)
True
>>>mylist.pop()
-2
>>>any(item for item in mylist if item < 0)
False
answers your first question.
>>> x = 3
>>> sum(item for item in mylist if item < x)
3
answers your second question.

Related

how to subtract elements within an array using for loops in python

I have an array a = [4,3,2,1]
What I am trying to achieve is that I need a single value on subtracting the elements in the array that is 4-3-2-1.
I tried the below this using for loop but it does not seem to work. I don't seem to get the right value on execution.
def sub_num(arr):
difference = arr[0]
n = len(arr)
print(n)
print(i)
for i in n: difference = arr[n] - arr[n-1]
return(difference)
If you have a list a:
a = [4, 3, 2, 1]
And wish to get the result of 4 - 3 - 2 - 1, you can use functools.reduce.
>>> from functools import reduce
>>> a = [4, 3, 2, 1]
>>> reduce(int.__sub__, a)
-2
>>>
You can solve with nested lists:
b = sum([a[0],*[-x for x in a[1:]]])
Simpler solution without for:
Since 4-3-2-1 is equal to 4-(3+2+1):
a[0]-sum(a[1:])
You could modify your code like this
def sub_num(arr):
difference = arr[0]
n = len(arr)
print(n)
for i in range(1,n):
difference = difference - arr[i]
return difference
Note:
Printing value of i without defining it is not possible

Count list occurence in list python

I'd like to count how many times a big list contains elements in specific order. So for example if i have elements [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5] and i'd like to know how many times [1,2,3] are next to each other (answer is 4 in this case).
I was thinking on checking the indexes of number '3' (so currently it'd return [2,7,12,17]. Then i would iterate over that list, take elements in positions described in the list and check two positions in front of it. If they match '1' and '2' then add 1 to counter and keep looking. I believe this solution isn't really efficient and does not look nice, would there be a better solution?
Here's a generalized solution that works for subsequences of any size and for elements of any type. It's also very space-efficient, as it only operates on iterators.
from itertools import islice
def count(lst, seq):
it = zip(*(islice(lst, i, None) for i in range(len(seq))))
seq = tuple(seq)
return sum(x == seq for x in it)
In [4]: count(l, (1, 2, 3))
Out[4]: 4
The idea is to create a sliding window iterator of width len(seq) over lst, and count the number of tuples equal to tuple(seq). This means that count also counts overlapping matches:
In [5]: count('aaa', 'aa')
Out[5]: 2
For lists of ints, you could convert to strings and then use the count method:
>>> x = [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]
>>> y = [1,2,3]
>>> s = ',' + ','.join(str(i) for i in x) + ','
>>> t = ',' + ','.join(str(i) for i in y) + ','
>>> s.count(t)
4
If the items in the list contained strings which contain commas, this method could fail (as #schwobaseggl points out in the comments). You would need to pick a delimiter known not to occur in any of the strings, or adopt an entirely different approach which doesn't reduce to the string count method.
On Edit: I added a fix suggested by #Rawing to address a bug pointed out by #tobias_k . This turns out to be a more subtle problem than it first seems.
x = [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]
y = [1,2,3]
count = 0
for i in range(len(x)-len(y)):
if x[i:i+len(y)] == y:
count += 1
print(count)
You could iterate the list and compare sublists:
In [1]: lst = [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]
In [2]: sub = [1,2,3]
In [3]: [i for i, _ in enumerate(lst) if lst[i:i+len(sub)] == sub]
Out[3]: [0, 5, 10, 15]
Note, however, that on a very large list and sublist, this is pretty wasteful, as it creates very many slices of the original list to compare against the sublist. In a slightly longer version, you could use all to compare each of the relevant positions of the list with those of the sublist:
In [5]: [i for i, _ in enumerate(lst) if all(lst[i+k] == e for k, e in enumerate(sub))]
Out[5]: [0, 5, 10, 15]
This strikes me as the longest common subsequence problem repeated every time until the sequence returned is an empty list.
I think that the best that you can do in this case for an efficient algorithm is O(n*m) where n is the number of elements in your big list and m is the number of elements in your small list. You of course would have to have an extra step of removing the small sequence from the big sequence and repeating the process.
Here's the algorithm:
Find lcs(bigList, smallList)
Remove the first occurrence of the smallList from the bigList
Repeat until lcs is an empty list
Return the number of iterations
Here is an implementation of lcs that I wrote in python:
def lcs(first, second):
results = dict()
return lcs_mem(first, second, results)
def lcs_mem(first, second, results):
key = ""
if first > second:
key = first + "," + second
else:
key = second + "," + first
if len(first) == 0 or len(second) == 0:
return ''
elif key in results:
return results[key]
elif first[-1] == second[-1]:
result = lcs(first[:-1], second[:-1]) + first[-1]
results[key] = result
return result
else:
lcsLeft = lcs(first[:-1], second)
lcsRight = lcs(first, second[:-1])
if len(lcsLeft) > len(lcsRight):
return lcsLeft
else:
return lcsRight
def main():
pass
if __name__ == '__main__':
main()
Feel free to modify it to the above algorithm.
One can define the efficiency of solution from the complexity. Search more about complexity of algorithm in google.
And in your case, complexity is 2n where n is number of elements.
Here is the solution with the complexity n, cause it traverses the list only once, i.e. n number of times.
def IsSameError(x,y):
if (len(x) != len(y)):
return False
i = 0
while (i < len(y)):
if(x[i] != y[i]):
return False
i += 1
return True
x = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
y = [1, 2, 3]
xLength = len(x)
yLength = len(y)
cnt = 0
answer = []
while (cnt+3 < xLength):
if(IsSameError([x[cnt], x[cnt+1], x[cnt+2]], y)):
answer.append(x[cnt])
answer.append(x[cnt+1])
answer.append(x[cnt + 2])
cnt = cnt + 3
else:
cnt = cnt + 1
print answer

Python remainder operator using list

Trying to use the remainder operator to find positive values in a list and print them as it finds them.
ExampleList=[2,5,-34,0,389,202,8]
I guess I don't understand how to make the operator use the list and then print the values.
import sys
li = [2,5,-34,0,389,202,8]
m = sys.maxint
print [e for e in li if e == e%m]
ExampleList=[2,5,-34,0,389,202,8]
for i in ExampleList:
if ((i % 10) != (abs(i) % 10)):
print (i)
The above code works for this particular example but might not work generally because there are numbers which no matter if they are positive or negative give the same modulus results.
Well, any solution using < or related comparisons or abs isn't actually using any unique features of %. So just for fun, a kinda silly way to do it without using any special functions, and with no comparisons other than == that actually use a behavior of % in a meaningful way (as opposed to just adding % to code that would produce the correct result without it) for this purpose:
>>> li = [2,5,-34,0,389,202,8]
>>> print([x for x in li if x == x % (x ** 2 + 1)])
[2, 5, 0, 389, 202, 8]
We square x to create a value known to be larger than the absolute value of x (and add 1 to handle the special cases of 0 and 1).
Another kind of tricky approach is to use the number as the divisor in such a way as to always get a fixed value from non-negative inputs:
# 1 % (x+2 or x+1) returns 1 for 0 or positive, non-1 for negative
# Use x+2 or x+1 to avoid ZeroDivisionError for x == 0
>>> print([x for x in li if 1 == 1 % (x+2 or x+1)])
[2, 5, 0, 389, 202, 8]
# We can even avoid using == by substituting subtraction since the result
# is a fixed 1 for non-negative, though it's pretty ugly looking
>>> print([x for x in li if not 1 % (x+2 or x+1) - 1])
[2, 5, 0, 389, 202, 8]
# Or if 0 shouldn't be included in results, tweak the divisor differently:
>>> print([x for x in li if 1 == 1 % (x+1 or x)])
[2, 5, 389, 202, 8]

Getting difference from all possible pairs from a list Python

I have an int list with unspecified number. I would like to find the difference between two integers in the list that match a certain value.
#Example of a list
intList = [3, 6, 2, 7, 1]
#This is what I have done so far
diffList = []
i = 0
while (i < len(intList)):
x = intList[i]
j = i +1
while (j < len(intList)):
y = intList[j]
diff = abs(x-y)
diffList.append(diff)
j += 1
i +=1
#Find all pairs that has a difference of 2
diff = diffList.count(2)
print diff
Is there a better way to do this?
EDIT: Made changes to the codes. This is what I was trying to do. What I want to know is what else can I use besides the loop.
seems like a job for itertools.combinations
from itertools import combinations
for a, b in combinations(intList, 2):
print abs(a - b)
You could even turn this one into a list comprehension if you wanted to :)
[abs(a -b) for a, b in combinations(intList, 2)]
int_list = [3, 6, 2, 7, 1]
for x in int_list:
for y in int_list:
print abs(x - y)

Python counting elements of a list within a list

Say I have the following list:
L=[ [0,1,1,1],[1,0,1,1],[1,1,0,1],[1,1,1,0] ]
I want to write a code will take a list like this one and tell me if the number of '1s' in each individual list is equal to some number x. So if I typed in code(L,3) the return would be "True" because each list within L contains 3 '1s'. But if I entered code(L,2) the return would be "False". I'm new to all programming, so I'm sorry if my question is hard to understand. Any help would be appreciated.
To see if each sublist has 3 1's in it,
all( x.count(1) == 3 for x in L )
Or as a function:
def count_function(lst,number,value=1):
return all( x.count(value) == number for x in lst )
L=[ [0,1,1,1],[1,0,1,1],[1,1,0,1],[1,1,1,0] ]
print(count_function(L,3)) #True
print(count_function(L,4)) #False
print(count_function(L,1,value=0)) #True
Assuming your lists contain only 1's and 0's, you can count the ones quite easily: sum(sl). You can get the set of unique counts for sub-lists and test that they all have three 1's as follows:
set( sum(sl) for sl in L ) == set([3])
While a little obscure compared to using the all() approach, this method also lets you test that all sub-lists have the same number of ones without having to specify the number:
len(set( sum(sl) for sl in L )) == 1
You can even "assert" that the sub-lists must all have the same number of 1's and discover that number in one operation:
[n] = set( sum(sl) for sl in L )
This assigns the number of 1's in each sub-list to n, but raises a ValueError if the sub-lists don't all have the same number.
If L is your base list and n is the number of 1 you expect in each "sublist", then the check looks like this:
map(sum, l) == [n] * len(l)
The whole function, along with tests, looks like this:
>>> def check(l, n):
return map(sum, l) == [n] * len(l)
>>> L=[ [0,1,1,1],[1,0,1,1],[1,1,0,1],[1,1,1,0] ]
>>> check(L, 3)
True
>>> check(L, 2)
False
EDIT: Alternative solutions include for example:
map(lambda x: x.count(1), l) == [n] * len(l)
set(i.count(1) for i in l) == {n} (the most efficient within this answer)
but I believe the cleanest approach is the one given by one of the other answerers:
all(i.count(1) == n for i in l)
It is even pretty self-explanatory.
def all_has(count, elem, lst)
"""ensure each iterable in lst has exactly `count` of `elem`"""
return all(sub_list.count(elem) == count for sub_list in lst)
>>> L = [ [0,1,1,1],[1,0,1,1],[1,1,0,1],[1,1,1,0] ]
>>> all_has(3, 1, L)
True
>>> all_has(2, 0, L)
False

Categories

Resources