Related
I'm trying to simplify this code so it doesn't use two for loops. The aim is to end up with a list of numbers that exist in one list but not the other ie. mutually exclusive.
Here is the code:
list1 = [1, 1, 2, 4, 6, 6, 9]
list2 = [1, 2, 3, 5, 6, 7, 8]
def mutually_exclusive(list1,list2):
new_list = []
for x in list1:
if x not in list2:
new_list.append(x)
else:
pass
for y in list2:
if y not in list1:
new_list.append(y)
else:
pass
return new_list
mutually_exclusive(list1,list2)
and the desired result:
[4, 9, 3, 5, 7, 8]
any help much appreciated thanks.
I have tried zip but doesn't yield all results.
You could also do it like this:
list1 = [1, 1, 2, 4, 6, 6, 9]
list2 = [1, 2, 3, 5, 6, 7, 8]
def mutually_exclusive(list1,list2):
return list(set(list1)^set(list2))
print(mutually_exclusive(list1, list2))
Result:
[3, 4, 5, 7, 8, 9]
You can do the following using symmetric_difference:
l1 = [1, 1, 2, 4, 6, 6, 9]
l2 = [1, 2, 3, 5, 6, 7, 8]
list(set(l1).symmetric_difference(set(l2)))
In [7]: l1
Out[7]: [1, 1, 2, 4, 6, 6, 9]
In [8]: l2
Out[8]: [1, 2, 3, 5, 6, 7, 8]
In [9]: list(set(l1).symmetric_difference(set(l2)))
Out[9]: [3, 4, 5, 7, 8, 9]
Write a Python program to replace the last element in a list with another list?
list is to be taken as an input.
Sample Input [1, 3, 5, 7, 9, 10], [2, 4, 6, 8]
Sample Output [1, 3, 5, 7, 9, 2, 4, 6, 8]
i tried to take the input using a = [int(x) for x in input().split()]
a = [int(x) for x in input().split()]
b = [int(y) for y in input().split()]
a[-1] = b
print(a)
error in line 1 and 3 invalid litral
>>> a = [[1, 3, 5, 7, 9, 10], [2, 4, 6, 8]]
>>> b = a[0][:-1] + a[1]
>>> b
[1, 3, 5, 7, 9, 2, 4, 6, 8]
this is also an option:
a = [1, 3, 5, 7, 9, 10]
b = [2, 4, 6, 8]
a.pop() # get rid of last element
a.extend(b) # extend list a with b data
print(a)
The eval() method returns the result evaluated from the expression
a,b = eval(input()) # input() is returning str, with eval convert string into lists
# print (a) # [1, 3, 5, 7, 9, 10]
# print (b) # [2, 4, 6, 8]
# use slicing to return list a without last element
# use operator + to conconate lists
result = a[:-1] + b
print (result)
output:
>>[1, 3, 5, 7, 9, 10], [2, 4, 6, 8]
[1, 3, 5, 7, 9, 2, 4, 6, 8]
Do not include commans (,) in your input if you are just going to use input.split().
input.split() will split on spaces. To split on commas, you should use input.split(',') or input.split(', ').
You could do it like this:
li1 = [1, 3, 5, 7, 9, 10]
li2 = [2, 4, 6, 8]
new_list = li1[:-1] + li2
print(new_list)
I am very new to coding and I was wondering if it is possible to limit an array in python to 100 items.
If it is possible, can you keep adding to that array and pushing out the old numbers in the array? So the oldest number should be pushed out to make room each time a new number is added.
Thank you very much in advance!
Yes, it's possible via collections.deque:
from collections import deque
lst = deque([], 100)
Like list.append, deque.append works in place:
A = deque(range(10), maxlen=10)
print(A)
deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
A.append(10)
print(A)
deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], maxlen=10)
What about creating a simple function to do this:
def add_to_array(lst, item, maxsize):
if len(lst) >= maxsize:
lst.pop(0)
lst.append(item)
Which works like this:
>>> lst = [i for i in range(1, 10)]
>>> lst
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> add_to_array(lst, 10, 10)
>>> lst
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> add_to_array(lst, 11, 10)
>>> lst
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Note: If your looking for something more efficient, you can use collections.deque, as pointed out in the other answer.
Here is an example of using deque to emulate your desired behaviour:
>>> lst = deque((i for i in range(1, 10)), maxlen=10)
>>> lst
deque([1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)
>>> lst.append(10)
>>> lst
deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], maxlen=10)
>>> lst.append(11)
>>> lst
deque([2, 3, 4, 5, 6, 7, 8, 9, 10, 11], maxlen=10)
new_list = []
i = 0
def remove_adjacent(nums):
global i
while i < len(nums) - 1:
if nums[i] != nums[i+1]:
new_list.append(nums[i])
else:
i += 1
remove_adjacent(nums[i:])
return
i += 1
l = [1, 2, 3, 5, 4, 4, 5, 5, 6, 7, 7, 7, 8, 8, 9, 8, 8]
remove_adjacent(l)
print new_list
Question: Given a list of numbers, return a list where all adjacent == elements have been reduced to a single element, so [1, 2, 2, 3] returns [1, 2, 3]. You may create a new list or modify the passed in list.
Issue: The final list printed consists of [1, 2, 3, 5] instead of [1, 2, 3, 5, 4, 5, 6, 7, 8, 9, 8]
What you would want is a problem best solved by itertools.groupby
l
Out[35]: [1, 2, 3, 5, 4, 4, 5, 5, 6, 7, 7, 7, 8, 8, 9, 8, 8]
from itertools import groupby
[k for k, _ in groupby(l)]
Out[36]: [1, 2, 3, 5, 4, 5, 6, 7, 8, 9, 8]
What itertools.groupby does is, it groups consecutive keys together by generating a tuple of the element and the consecutive group as a list
To get a clear understanding of itertools.groupby, you can dump the resultant list of tuples generated by grouping the list of consecutive numbers
[(k, list(g)) for k, g in groupby(l)]
Out[40]:
[(1, [1]),
(2, [2]),
(3, [3]),
(5, [5]),
(4, [4, 4]),
(5, [5, 5]),
(6, [6]),
(7, [7, 7, 7]),
(8, [8, 8]),
(9, [9]),
(8, [8, 8])]
new_list = []
def remove_adjacent(nums):
i = 0
while i < len(nums) - 1:
if nums[i] != nums[i+1]:
new_list.append(nums[i])
else:
i += 1
remove_adjacent(nums[i:])
return
i += 1
l = [1, 2, 3, 5, 4, 4, 5, 5, 6, 7, 7, 7, 8, 8, 9, 8, 8]
remove_adjacent(l)
# appending the last item
new_list.append(l[len(l)-1])
print (new_list.append(nums[len(nums) - 1]))
Output
[1, 2, 3, 5, 4, 5, 6, 7, 8, 9, 8]
This is perfect for a generator. I'm not altering the original list. Instead, I'm returning a new list with no adjacent values equal to one another.
def removerator(l):
last = None
for x in l:
if x != last:
last = x
yield x
list(removerator(l))
[1, 2, 3, 5, 4, 5, 6, 7, 8, 9, 8]
Setup
l = [1, 2, 3, 5, 4, 4, 5, 5, 6, 7, 7, 7, 8, 8, 9, 8, 8]
I made a function where it get a list and iterate over its items, then it adds the items that aren't the same as the items already added to the list in the previous iteration.
l = [1, 2, 3, 5, 4, 4, 5, 5, 6, 7, 7, 7, 8, 8, 9, 8, 8] # List that we want to change
def remove_adjacent(l): # Define a new function and accept an argument: the list to check.
new = [l[0]] # Make a new list (temporal) and assing like it's first item the first item of the main list. It's the same as new = [] and new.append(l[0]).
for item in l[1:]: # We iterate across the list, but we don't iterate on the first item because we've alreaday added it to the list, if you want you can delete the slice in [1:] since it will only make the iteration a really small fraction more slowly.
if new[-1] != item: # We check if the new item is the same as the last item added to the new list, if not, we add it.
new.append(item) # We add the item to the new list.
return new # We return the list.
print(remove_adjacent(l)) # We check it.
# [1, 2, 3, 5, 4, 5, 6, 7, 8, 9, 8]
If I have a list where all values are unique, the code runs fine. However, if there is a duplicate value within the list, when finding the minimum value for the next iteration, it pulls from the entire list rather than just the remainder of the list.
for n in range(0,len(lst)):
a = min(lst[n:]) #minimum value within remainder of set
i = lst.index(a) #index value for minimum value within remainder of set
temp = lst[n]
lst[n] = a
lst[i] = temp
Results look like this:
lst = [6, 8, 9, 1, 3, 4, 7, 5, 4]
[1, 8, 9, 6, 3, 4, 7, 5, 4]
[1, 3, 9, 6, 8, 4, 7, 5, 4]
[1, 3, 4, 6, 8, 9, 7, 5, 4]
[1, 3, 6, 4, 8, 9, 7, 5, 4]
[1, 3, 6, 8, 4, 9, 7, 5, 4]
[1, 3, 6, 8, 9, 4, 7, 5, 4]
[1, 3, 6, 8, 9, 7, 4, 5, 4]
[1, 3, 6, 8, 9, 7, 5, 4, 4]
[1, 3, 6, 8, 9, 7, 5, 4, 4]
I'm looking for it to return this:
[1, 3, 4, 4, 5, 6, 7, 8, 9]
When n is 4, the next minimum is 4 again, but lst.index() finds the first 4 at position 3 instead.
Start searching for the miminum from n; the .index() method takes a second argument start, from where to start searching:
i = lst.index(a, n)
Note that Python can assign to two targets in place, no need to use a temporary intermediate. range() with just one argument starts from 0:
for n in range(len(lst)):
a = min(lst[n:])
i = lst.index(a, n)
lst[n], lst[i] = a, lst[n]
Demo:
>>> lst = [6, 8, 9, 1, 3, 4, 7, 5, 4]
>>> for n in range(0,len(lst)):
... a = min(lst[n:])
... i = lst.index(a, n)
... lst[n], lst[i] = a, lst[n]
...
>>> lst
[1, 3, 4, 4, 5, 6, 7, 8, 9]