Apply Indicator Function to List - python

Is there an easy way to apply an indicator function to a list? i.e. I have a list with some numbers in it and I would like to return another list of the same size with, for example, ones where the positive numbers were in the original list and zeros where the negative numbers were in the original list.

Just use a list comprehension:
>>> orig = [-3, 2, 5, -6, 8, -2]
>>> indic = [1 if x>0 else 0 for x in orig]
>>> indic
[0, 1, 1, 0, 1, 0]

List comprehensions!
bysign = [int(x >= 0) for x in somelist]
Here's a demo.

To produce the results of your example, I probably would have done
cmp_list=map(cmp, your_list)
one_zero_list=[]
for item in cmp_list:
if item < 0:
one_zero_list.append(0)
elif item==0:
one_zero_list.append(0) #you didnt actually say what to do with 0
else:
one_zero_list.append(1)

Related

Check if content of index equals content of next index

array = [1, 1, 1, 1, 1, 1, 2]
new_array = [x for x in array if array[array.index(x)] != array[array.index(x) + 1]]
print(new_array)
Hi, I'm trying to write a program that will check if a content of an index (example: list[0]) equals to next index and if not append the number that differs and I tried to use a new skill I learned which is list comprehension and I don't quite understand why doesn't it work how it should work
To make it more clear what I mean is if I am given an array with all numbers the same except one number which in this case is two I want to append it in a list I also added a picture to make it even more clear
You can use this simple one liner
print(a[0] if a.count(a[0]) == 1 else min(set(a).difference(a[:1])))
Note: I'm using min() to just to get the element from set.
Output:
>>> a=[1, 1, 2]
>>> print(a[0] if a.count(a[0]) == 1 else min(set(a).difference(a[:1])))
2
>>> a = [17, 17, 3, 17, 17, 17, 17]
>>> print(a[0] if a.count(a[0]) == 1 else min(set(a).difference(a[:1])))
3
IndexError: list index out of range means you are passing an index that isn't present in the list. And that error is raised in this part:
array[array.index(x) + 1]
When x is the last element error is raised. Because there is no index after the last element. In your case, using list comprehension isn't the best choice, you should prefer for loop.
it may help you:
list = [1, 1, 2, 3, 4, 4]
for i, j in enumerate(list[:-1]):
if j == list[i+1]:
#dosomething

Assigning a random number to individual array elements that meet a certain criteria

I need to find all the elements in an array that are >0 and then replace each one with a random number between 0 and 5 in Python 3.
I have made an array (called L) of 20 elements that each equal 0 or 1, but am struggling to replace elements individually. (However in future this may equal a range of numbers, so I need >0 and not just =1)
I do not want
speed = np.random.randint(0,5)
L[L > 0] = speed
as this changed all the elements >0 to the same random number.
Any ideas?
Perhaps this will help you.
from random import *
L = [0,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0]
i=0
for n in L:
x = randint(1, 5) # Pick a random number between 1 and 5.
if n > 0:
L[i] = x
i+=1
print(L)
Perhaps this?
I instantiate L with a special pattern, so that it should be easy to discern if the code does what's intended.
>>> import random
>>> L = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
>>> list(map(lambda x: random.randint(0,5) if x>0 else x, L))
[0, 0, 0, 0, 0, 3, 2, 2, 4, 5]
I should mention that this code does not replace individual elements in L. It creates a new list. However, unless the list is especially large this would make no difference, in fact might be slightly faster. (This might be why someone down-voted. You just can't please everyone.)

remove non repeating characters from a list

I am trying to remove non repeating characters from a list in python. e.g list = [1,1,2,3,3,3,5,6] should return [1,1,3,3].
My initial attempt was:
def tester(data):
for x in data:
if data.count(x) == 1:
data.remove(x)
return data
This will work for some inputs, but for [1,2,3,4,5], for example, it returns [2,4]. Could someone please explain why this occurs?
l=[1,1,2,3,3,3,5,6]
[x for x in l if l.count(x) > 1]
[1, 1, 3, 3, 3]
Adds elements that appear at least twice in your list.
In your own code you need to change the line for x in data to for x in data[:]:
Using data[:] you are iterating over a copy of original list.
There is a linear time solution for that:
def tester(data):
cnt = {}
for e in data:
cnt[e] = cnt.get(e, 0) + 1
return [x for x in data if cnt[x] > 1]
This is occurring because you are removing from a list as you're iterating through it. Instead, consider appending to a new list.
You could also use collections.Counter, if you're using 2.7 or greater:
[a for a, b in collections.Counter(your_list).items() if b > 1]
Another linear solution.
>>> data = [1, 1, 2, 3, 3, 3, 5, 6]
>>> D = dict.fromkeys(data, 0)
>>> for item in data:
... D[item] += 1
...
>>> [item for item in data if D[item] > 1]
[1, 1, 3, 3, 3]
You shouldn't remove items from a mutable list while iterating over that same list. The interpreter doesn't have any way to keep track of where it is in the list while you're doing this.
See this question for another example of the same problem, with many suggested alternative approaches.
you can use the list comprehention,just like this:
def tester(data):
return [x for x in data if data.count(x) != 1]
it is not recommended to remove item when iterating

Using functions on lists

I have a function that determines if the number is less than 0 or if there isn't a number at all
def numberfunction(s) :
if s == "":
return 0
if s < 0 :
return -1
if s > 0:
return s
i also have a list of lists
numbers = [[]]
now, lets say i filled the list of lists with numbers like:
[[1,2,3,4],[1,1,1,1],[2,2,2,2] ..etc ]
how would i go about calling up the function i had above into the numbers i have in the lists?
Would I require a loop where I use the function on every number of every list, or is it simpler than that?
You can use map and a list comprehension to apply your function to all of your elements. Please note that I have modified your example list to show all of the return cases.
def numberfunction(s) :
if s == "":
return 0
if s < 0 :
return -1
if s > 0:
return s
# Define some example input data.
a = [[1,2,3,""],[-1,1,-1,1],[0,-2,-2,2]]
# Apply your function to each element.
b = [map(numberfunction, i) for i in a]
print(b)
# [[1, 2, 3, 0], [-1, 1, -1, 1], [None, -1, -1, 2]]
Note that, with the way your numberfunction works at the moment, it will return None for an element equal to zero (thanks to #thefourtheye for pointing this out).
You can also call nested map():
>>> a = [[1,2,3,""],[-1,1,-1,1],[2,-2,-2,2]]
>>> map(lambda i: map(numberfunction, i), a)
[[1, 2, 3, 0], [-1, 1, -1, 1], [2, -1, -1, 2]]
>>>
I have Python < 3 in which map returns list.
You could do it as:
result = [[numberfunction(item) for item in row] for row in numbers]

return a list containing elements of another list

I need to write an expression and I'm completely stuck. I have part of the code that I think I have written correctly but I'm stick on the rest of it. I need the code to return a new list containing every 3rd element in the list, starting at index 0.
For example: if I have the list [0, 1, 2, 3, 4, 5] I need it to return [0, 3]
The code I have so far is:
result = []
i = 0
while i < len(L):
result.append(L[i])
i =
return result
Can someone please help me figure out what I need the i = expression to be for this code to work.
First of all, you can make use of extended slice notation to make things easier:
In [1]: l = [0, 1, 2, 3, 4, 5]
In [2]: l[::3]
Out[2]: [0, 3]
From the docs:
Some sequences also support “extended slicing” with a third “step” parameter: a[i:j:k] selects all items of a with index x where x = i + n*k, n >= 0 and i <= x < j.
As for your code sample, you probably need i = i + 3 or i += 3 there.
Maybe try this:
result = []
for i in range(0, len(L), 3):
result.append(L[i])
return result
Another alternative is to use enumerate.
[j for i, j in enumerate([0, 1, 2, 3, 4, 5]) if i % 3 == 0]
this will give tyou an iterable sequence:
import itertools
l = [0, 1, 2, 3, 4, 5]
itertools.islice(l, 0, None, 3)
to turn it into a list, use the list() function.
impiort itertools
def get_sublist(l):
return list(itertools.islice(l, 0, None, 3))
python 3.2
one way:
>>> [i for i in range(0,len(L),3)]
[0,3]
your method:
result = []
i = 0
while i <= len(L):
result.append(L[i])
i+=3
return result

Categories