Remove all occurrences of an integer from list - python

In python, how can I remove all occurrences of an integer from a list. For example:
list_a = [5, 20, 15, 10, 55, 30, 65]
list_a.METHOD(5)
print(list_a)
[20, 10, 30]
Essentially, the method removes anything that contains a 5. Not specifically multiples of 5, given that 10 and 20 do not contain a 5. Thanks.

list_a = [5, 20, 15, 10, 55, 30, 65]
list_a = [x for x in list_a if "5" not in str(x)]
print(list_a)
[20, 10, 30]

This is one way:
[x for x in list_a if str(x).find('5') < 0]
That's a list comprehension that converts each number to a string and then searches the string for the character 5. find returns -1 if not found so we keep only things where the 5 wasn't found.

You can use filter and lambda.
filter(lambda x:"5" not in str(x) , [5, 20, 15, 10, 55, 30, 65])

Related

Replace elements in lists based on indexes python

Community of stackoverflow:
I have a list "rest" which is the following:
rest=[5, 7, 11, 4]
I have another list which is b:
b=[21, 22, 33, 31, 23, 15, 19, 13, 6]
And I have a "last" list:
last=[33, 19, 40, 21, 31, 22, 6, 15, 13, 23]
I have to replace the first 4 elements in b with the elements in rest. How can I replace the elements in last according to the matches with b to get the rest elements?
for example:
5 7 11 4 #elements from rest
b= [21, 22, 33, 31, 23, 15, 19, 13, 6]
to get last list as the following:
last=[11, 19, 40, 5, 4, 7, 6, 15, 13, 23] #elements that matched with b were replaced by rest
How can I do this?
Try this:
rest=[5, 7, 11, 4]
b=[21, 22, 33, 31, 23, 15, 19, 13, 6]
last=[33, 19, 40, 21, 31, 22, 6, 15, 13, 23]
for i, l in enumerate(last):
if l in b:
if b.index(l) < len(rest):
last[i] = rest[b.index(l)]
print(last)
You can try to do something like this...
rest_change_index = 0
for i in range(len(b)):
if b[i] in last:
last_change_index = last.index(b[i])
last[last_change_index] = rest[rest_change_index]
rest_change_index += 1
print(last)
This iterates through the elements of b, and if an element in last matches the element of b being iterated through in the loop, then it changes that value with the corresponding element of rest (first element of rest for first matching instance, etc.). Let me know if this makes sense.
You can do this as follows:
# Get first 4 items in b
b4 = b[:4]
# Create mapping from b to rest
b_to_rest = dict(zip(b4, rest))
# Use dictionary .get to either replace if in rest or keep if not
last = [b_to_rest.get(x,x) for x in last]
Firstly, I've defined b4 as the first 4 items in b. Then I've used zip and dict to map b values to rest values. Finally I use a list comprehension to replace the items in last. .get(x,x) means try to get x from the dictionary, if it doesn't exist just use x.

I need to generate x amount of unique lists inside another list

I am able to generate the desired output but i need 10 of them and each list has to be unicue. The best solution i thought of was to create a 2nd function, generate a emty list and populate each element with list from 1st function. The output i got so far is x amount of lists but they are not unique and python gives me error when i try to call on the first function inside the 2nd one.
import random
numbers = list(range(1, 35))
out = []
final = []
print(numbers) # to see all numbers
# returns 7 unique pop'd numbers from list 'numbers' and appends them to list 'out'
def do():
for x in range(7):
out.append(numbers.pop(random.randrange(len(numbers))))
print(sorted(out))
# In other words i want to print output from function do() 10 times but each item in list has to be unique, not the lists themself
def do_ten():
for x in range(10):
final.append(out)
# do() python doesnt like this call
print(sorted(final))
do_ten()
This generates a specific amount of lists, in a list, which contain random numbers from 1 to 100, you can use l and n to control the amount of lists and numbers respectively.
import random
l, n = 3, 5 # The amount of lists and numbers respectively.
lis = [[i for i in random.sample(range(1, 35), n)] for group in range(l)]
print(lis)
Random Output:
[[16, 11, 17, 13, 9], [26, 6, 16, 29, 24], [24, 2, 4, 1, 20]]
You are popping 10 times 7 numbers from a list containing 34 elements (from 1 to 34). This is not possible. You need to have at least 70 elements in your list numbers(for example, from 0 to 69).
This is a solution that should work, based on the code you've already written:
import random
numbers = list(range(0, 70))
final = []
print(numbers) # to see all numbers
# returns a list of 7 unique popped numbers from list 'numbers'
def do():
out = []
for x in range(7):
l = len(numbers)
r = random.randrange(l)
t = numbers.pop(r)
out.append(t)
return out
# Call 10 times do() and add the returned list to 'final'
def do_ten():
for x in range(10):
out = do() # Get result from do()
final.append(out) # Add it to 'final'
do_ten()
print(final)
Does it help:
num_lists = 10
len_list = 10
[list(np.random.randint(1,11,len_list)) for _ in range(num_lists)]
As some people may have different definitin of "uniqueness", you may try:
source_list = range(0, num_lists*len_list,1)
[list(np.random.choice(source_list, len_list, replace=False)) for _ in range(num_lists)]
Pulling 7 of 34 numbers from your numberrange without repeats can be done using random.sample - to ensure you do not get duplicate lists, you can add a tuple of the list to a set and your final result and only add to final if this tuple is not yet in the set:
import random
numbers = range(1, 35) # 1...34
final = []
chosen = set()
while len(final) < 10:
# replace popping numbers with random.sample
one_list = random.sample(numbers, k=7) # 7 numbers out of 34 - no repeats
# create a tuple of this list and only add to final if not yet added
t = tuple(one_list)
if t not in chosen:
chosen.add(t)
final.append(one_list)
print (final)
Output:
[[1, 5, 10, 26, 14, 33, 6],
[3, 11, 1, 30, 7, 21, 18],
[24, 23, 28, 2, 13, 18, 1],
[4, 25, 32, 15, 22, 8, 27],
[32, 9, 10, 16, 17, 26, 12],
[34, 32, 10, 26, 16, 21, 20],
[6, 34, 22, 11, 26, 12, 5],
[29, 17, 25, 15, 3, 6, 5],
[24, 8, 31, 28, 17, 12, 15],
[6, 19, 11, 22, 30, 33, 15]]
If you dont need unique resulting lists, you can simplify this to a one-liner but it might have dupes inside:
final = [random.sample(range(1,11),k=7) for _ in range(10)]

Reversed returning same index if value is the same

This works fine for my purposes, except that when the value (in this case 20) is the same, it will only return the index from the front. Code is as follows, I'm not sure what the workaround is, but I need it to return the index of the value from reversed. I have some floats that would differ, but seem more difficult to work with.
lmt_lst = [-1, 5, 9, 20, 44, 37, 22, 20, 17, 12, 6, 1, -6]
lft_lmt = next(x for x in lmt_lst if x >=20)
rgt_lmt = next(x for x in reversed(lmt_lst) if x >= 20)
lft_idx = lmt_lst.index(lft_lmt)
rgt_lmt = lmt_lst.index(rgt_lmt)
print('Left Limit:', lft_lmt, 'Left Index:', lft_idx)
print('Right Limit:', rgt_lmt, 'Right Index:', rgt_idx)
If you change either of the values of '20' to 21, it works just fine
It does not return any errors, just returns the first index of the value, regardless of reversed
Your lft_lmt and rgt_lmt lists only contain values greater than or equal to 20, so your lists are [20, 44, 37, 22, 20] and [20, 22, 37, 44, 20] respectively.
>>> lmt_lst = [-1, 5, 9, 20, 44, 37, 22, 20, 17, 12, 6, 1, -6]
>>> [x for x in lmt_lst if x >=20]
[20, 44, 37, 22, 20]
>>> [x for x in reversed(lmt_lst) if x >= 20]
[20, 22, 37, 44, 20]
The first item of both of these lists is 20, and so when you search for them (using .index which searches from the beginning of the list) in the initial list you'll get 3 both times (because 20 is found at position 3 no matter how many times you search the list from beginning to end).
To find your right index you want to search the reversed list and account for the result being as if searching the list backwards:
>>> lft_idx = lmt_lst.index(lft_lmt)
>>> lft_idx
3
>>> rgt_idx = len(lmt_lst) - 1 - lmt_lst[::-1].index(rgt_lmt)
>>> rgt_idx
7

Merging an existing list into the middle of a Python list literal

When declaring a list literal in Python, is it possible to merge an existing list into the declaration? For example:
l = [1, 2, 3]
n = [10, 20, 30, l, 50, 60, 70]
This results in the following:
[10, 20, 30, [1, 2, 3], 50, 60, 70]
Note that the list l itself has been added as a single element, but what I really want is for l's elements to be added individually to the target list, like this:
[10, 20, 30, 1, 2, 3, 50, 60, 70]
As of Python 3.5 (See https://www.python.org/downloads/release/python-350/, PEP448), This can be done using Python's unpack operator, which is an asterisk before the list:
l = [1, 2, 3]
n = [10, 20, 30, *l, 50, 60, 70]
The result is:
[10, 20, 30, 1, 2, 3, 50, 60, 70]
This will works with l on any place
from itertools import chain
for i in n:
if isinstance(i, list):
b+=list(chain(i))
else:
b+=[i]

Multiplying two sets of numbers in python

I have two lists of numbers, say [1, 2, 3, 4, 5] and [7, 8, 9, 10, 11], and I would like to form a new list which consists of the products of each member in the first list with each member in the second list. In this case, there would be 5*5 = 25 elements in the new list.
I have been unable to do this so far with a while() loop.
This is what I have so far:
x = 0
y = 99
results = []
while x < 5:
x = x + 1
results.append(x*y)
while y < 11:
y = y + 1
results.append(x*y)
Use itertools.product to generate all possible 2-tuples, then calculate the product of that:
[x * y for (x, y) in itertools.product([1,2,3,4,5], [7,8,9,10,11])]
The problem is an example of an outer product. The answer already posted with itertools.product is the way I would do this as well.
But here's an alternative with numpy, which is usually more efficient than working in pure python for crunching numeric data.
>>> import numpy as np
>>> x1 = np.array([1,2,3,4,5])
>>> x2 = np.array([7,8,9,10,11])
>>> np.outer(x1,x2)
array([[ 7, 8, 9, 10, 11],
[14, 16, 18, 20, 22],
[21, 24, 27, 30, 33],
[28, 32, 36, 40, 44],
[35, 40, 45, 50, 55]])
>>> np.ravel(np.outer(x1,x2))
array([ 7, 8, 9, 10, 11, 14, 16, 18, 20, 22, 21, 24, 27, 30, 33, 28, 32,
36, 40, 44, 35, 40, 45, 50, 55])
Wht dont you try with known old ways;
list1 = range(1, 100)
list2 = range(10, 50, 5)
new_values = []
for x in list1:
for y in list2:
new_values.append(x*y)
Without any importing, you can do:
[x * y for x in range(1, 6) for y in range(7, 12)]
or alternatively:
[[x * y for x in range(1, 6)] for y in range(7, 12)]
To split out the different multiples, but it depends which order you want the results in.
from functools import partial
mult = lambda x, y: x * y
l1 = [2,3,4,5,5]
l2 = [5,3,23,4,4]
results = []
for n in l1:
results.extend( map( partial(mult, n) , l2) )
print results

Categories