Removing common values from two lists in python - python

Hi let's say that I have two lists in python and I want to remove common values from both lists. A potential solution is:
x = [1, 2, 3, 4, 5, 6, 7, 8]
y = [43, 3123, 543, 76, 879, 32, 14241, 342, 2, 3, 4]
for i in x:
if i in y:
x.remove(i)
y.remove(i)
it seems correct but it is not. The reason, I guess, is because by removing an item from the list the index continues to iterate. Therefore, for two common values in the lists where the values are near each other we will be missing the later values (the code will not iterate through it).
The result would be:
>>> x
[1, 3, 5, 6, 8, 9, 10]
>>> y
[43, 3123, 543, 76, 879, 32, 14241, 342, 3]
So we are missing the value '3'.
Is the reason of that behaviour the one that I mentioned? or am I doing something else wrong?

Just slight change your code,Iterate through the copy of x it's x[:].You are modifying the list while iterating over it. So that's why you are missing value 3
for i in x[:]:
if i in y:
x.remove(i)
y.remove(i)
And alternative method
x,y = [i for i in x if i not in y],[j for j in y if j not in x]

You can also use difference of set objects.
a = list(set(y) - set(x))
b = list(set(x) - set(y))

z=[i for i in x if i not in y]
w=[i for i in y if i not in x]
x=z
y=w
That should do the trick? It's a bit less memory efficient.

If you use numpy, then all you need is:
x, y = np.setdiff1d(x, y), np.setdiff1d(y, x)
and if you don't want to use numpy:
x, y = list(set(x).difference(y)), list(set(y).difference(x))

I personally think Python's set data type is the way to go:
You can do something like this:
>>> x = [1, 2, 3, 4, 5, 6, 7, 8]
>>> y = [43, 3123, 543, 76, 879, 32, 14241, 342, 2, 3, 4]
>>> sx = set(x)
>>> sy = set(y)
>>> sx.union(sy)
set([1, 2, 3, 4, 5, 6, 7, 8, 32, 43, 76, 342, 543, 879, 3123, 14241])
Or you can reduce it to a one liner:
list(set(x).union(set(y)))

You can use set method to remove elements in list.
s1=input()
s2=input()
str=list(set(s1).symmetric_difference(set(s2)))
print(str)

Related

How to get the values in the dictionary into the list form and then square them into list

I have a dictionary of values in tuple form, how to get the values in list form.
I want to get values from the tuples and create new lists and create another 3 lists with squares from them.
dictionary={1:(1,2,3),2:(3,4,5),3:(6,7,8),4:(9,10,11),5:(12,13,14)}
s=list(d.values())
d=[item for t in s for item in t]
print(d)
I used list comprehension i got this output:
[1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
Using list comprehension
Expected_output:
[1,3,6,9,12],
[2,4,7,10,13],
[3,5,8,11,14],
squares**2 output above three list :
[1,9,36,81,144],
[4,16,49,100,169],
[9,25,64,121,196]
Provided with a Dictionary
First take a empty list and assign it to a variable “l”
Using list comprehension separate the values and store that in a variable
Iterate the values and append the empty list “l”
Now iterate the “l” using index values i[o], i[1], i[2] and store in various variables respectively
Using map function square the variables and store the values and print them using the list of variables
x = {
1:(1,2,3),
2:(4,5,6),
3:(7,8,9),
4:(10,11,12),
5:(13,14,15)
}
l = []
y = [i for i in x.values()]
for i in y:
l.append(i)
print(l)
m = [i[0] for i in l]
n = [i[1] for i in l]
o = [i[2] for i in l]
m1 = map(lambda i:i**2, m)
n1 = map(lambda i:i**2, n)
o1 = map(lambda i:i**2, o)
print(m)
print(list(m1))
print(n)
print(list(n1))
print(o)
print(list(o1))
you can use zip to collect the index elements of each list together, then use list comprehension to square them
dictionary={1:(1,2,3),2:(3,4,5),3:(6,7,8),4:(9,10,11),5:(12,13,14)}
list_vals = list(zip(*dictionary.values()))
squares = [[num ** 2 for num in nums] for nums in list_vals]
print(list_vals)
print(squares)
OUTPUT
[(1, 3, 6, 9, 12), (2, 4, 7, 10, 13), (3, 5, 8, 11, 14)]
[[1, 9, 36, 81, 144], [4, 16, 49, 100, 169], [9, 25, 64, 121, 196]]
Thanks to comments from #roganjosh highlighting that the dict will only be assured to be ordered if the pythong version is 3.6 or higher. If your python version is less than that you would first need to sort the values by order of the keys. Below is an example.
dictionary={2:(3,4,5),3:(6,7,8),4:(9,10,11),5:(12,13,14),1:(1,2,3)}
ordered_key_val = sorted(dictionary.items(), key=lambda items: items[0])
list_vals = list(zip(*[val for key, val in ordered_key_val]))
squares = [[num ** 2 for num in nums] for nums in list_vals]
print(list_vals)
print(squares)
You can use numpy to transpose the entire list once the values of the dictionary are obtained. You can use the below program
import numpy as np
dictionary={1:(1,2,3),2:(3,4,5),3:(6,7,8),4:(9,10,11),5:(12,13,14)}
list_out= []
for i in dictionary.keys():
list_out.append(dictionary[i])
tran_list = np.transpose(list_out)
out_list = tran_list*tran_list
Output of this is:
>>> out_list
array([[ 1, 9, 36, 81, 144],
[ 4, 16, 49, 100, 169],
[ 9, 25, 64, 121, 196]])
This is an array output! Anyway if you want it only in the list, ofcourse , you can play with it!
You can do this way:
>>> temp = list(zip(*dictionary.values()))
>>> [list(i) for i in temp]
[[1, 3, 6, 9, 12], [2, 4, 7, 10, 13], [3, 5, 8, 11, 14]]
>>> [[i**2 for i in elem] for elem in temp]
[[1, 9, 36, 81, 144], [4, 16, 49, 100, 169], [9, 25, 64, 121, 196]]
I have one dictionary here
d={1:(1,2,3),2:(4,5,6),3:(7,8,9),4:(10,11,12),5:(13,14,15)}
first I want to get values in tuple in three lists then I used list comprehension here The below code gives the tuple values in three lists
myList1 = [d [i][0] for i in (d.keys()) ]
print(myList1)
myList2 = [d [i][1] for i in (d.keys()) ]
print(myList2)
myList3 = [d [i][2] for i in (d.keys()) ]
print(myList3)
Here all the tuple values converted into list form
[1, 4, 7, 10, 13]
[2, 5, 8, 11, 14]
[3, 6, 9, 12, 15]
Now I want to squares the elements in three lists here I Used lambda expression the below code squares the elements in the lists
a1= list(map(lambda x: x**2 ,myList1))
print(a1)
a2= list(map(lambda x: x**2 ,myList2))
print(a2)
a3= list(map(lambda x: x**2 ,myList3))
print(a3)
The output is:
[1, 16, 49, 100, 169]
[4, 25, 64, 121, 196]
[9, 36, 81, 144, 225]

Producing array of which its elements are indices

I'm trying to remove values from a large data set that are inconsistent in my analysis.
Here is the current method i'm started with.
For example, lets say I have an array a that consist of an number of elements.
a = [30, 40, 200, 324, 8, 67, 789, 9, 567, 2143, 13]
idx = [(i,value) for i,value in enumerate(a) if value<=10]
print idx
>>> [(4, 8), (7, 9)]
How do i go about to where I can only just create an array that consist of only its indices
print idx
>>> [4, 8]
Don't include the value in the comprehension result:
idx = [i for i, v in enumerate(a) if v <= 10]
You are almost there, just only use the index:
>>> a = [30, 40, 200, 324, 8, 67, 789, 9, 567, 2143, 13]
>>> idx = [i for i, value in enumerate(a) if value<=10]
>>> idx
[4, 7]

Sort a list based on unit place, tens place, hundred place digit in Python

Suppose I have a list, I want to sort the digits in the following pattern:
A = [3, 30, 34, 256, 5, 9]
Sort by unit place digit first, if unit place digit is same then we will compare tens place and then hundred place. If you sort the A by this rule then:
A = [9, 5, 34, 3, 30, 256]
9 is the highest digit at Unit place
5 is second highest
3, 34, 30 since unit digit is same here, we will compare tens place so 34 will come first here, then 3 and 30.
256 will come last since its unit place digit is 2 which is the lowest.
Suppose B = [100, 10, 1]
then after sorting B = [1, 10, 100]
Could anyone share some Pythonic way to solve this issue?
I have tried sorted(nums, key=lambda x: int(x[0]), reverse=True) but here how will I take tenth place digit into account?
Update: There is one point missing suppose A = [1, 100, 10] then in such cases after sorting A = [1, 10, 100]. In the example I gave A = [3, 30, 34, 256, 5, 9] here after sorting A = [9, 5, 34, 3, 30, 256].
Overall logic is I want to join all digits and create a largest
number.
I think you just want str as the key:
In [11]: sorted(A, key=str, reverse=True)
Out[11]: [9, 5, 34, 30, 3, 256]
Initially I read your question that you would want the reversed digits:
In [12]: sorted(A, key=lambda x: str(x)[::-1])
Out[12]: [30, 3, 34, 5, 256, 9]
The following code answers the updated question: "sort in a way that concatenated sorted numbers will give the highest possible number".
The idea is if most significant digits are same and length is different the longer number is "greater" than the shorter number if in longer number the (shorter number length + 1) digit is greater or equal than the most significant digit. Eg: 30 < 3, 32 < 3, 35 > 3, 10 < 1, 3003 > 3, 3001 < 3, 345 > 34, 342 < 34.
>>> def f(x, y):
... if x == y:
... return 0
... xs = str(x)
... ys = str(y)
... for i in range(min(len(xs), len(ys))):
... if xs[i] > ys[i]:
... return 1
... elif xs[i] < ys[i]:
... return -1
... if len(xs) > len(ys):
... return 1 if xs[0] <= xs[len(ys)] else -1
... return -1 if ys[0] <= ys[len(xs)] else 1
...
>>> A = [3, 30, 34, 256, 5, 9]
>>> B = [100,10,1]
>>> sorted(A, cmp=f, reverse=True)
[9, 5, 34, 3, 30, 256]
>>> sorted(B, cmp=f, reverse=True)
[1, 10, 100]
Oh, you did really want a numbers-as-text string sort. Well if you wanted the units -> tens -> hundreds sort you described, this does it:
# Repeatedly modulo 10 to get the rightmost digit
# (units, then tens, then hundreds) until the
# digit where the two numbers differ. Compare those two digits.
>>> def f(x, y):
... xr = x % 10
... yr = y % 10
... while x and y and xr == yr:
... x, xr = divmod(x, 10)
... y, yr = divmod(y, 10)
... return cmp(xr, yr)
...
>>> A = [3, 30, 34, 256, 5, 9]
>>> sorted(A, cmp=f)
[30, 3, 34, 5, 256, 9]
It's not sorting as your example output, but it is sorting by units - 0, 3, 4, 5, 6, 9. And if it had any where the units were the same, it sorts by tens, etc.
>>> A = [3, 30, 34, 266, 256, 5, 9]
>>> sorted(A, cmp=f)
[30, 3, 34, 5, 256, 266, 9]
This is a different version from other previously posted answers:
import itertools
def produce_list(A):
At = [str(x) for x in A] # convert the items to str so we can join them
result = 0
for i in itertools.permutations(At): # go through all permutations
temp = int(''.join(i))
if result < temp: # find the biggest value of the combined numbers
result = temp
result_list = list(i)
return [int(x) for x in result_list] # return the list of ints
print produce_list([3, 30, 34, 256, 5, 9])
print produce_list([100, 1, 10])
It might not be very efficient (it will go through every combination) but it is as Pythonic as I could get.

Unable to understand why this Python FOR loop isn't working as intended

I'm trying to generate a random dataset to plot a graph in Python 2.7.
In which the 'y' list stores 14 integers between 100 and 135. I did that using the following code:
y = [random.randint(100, 135) for i in xrange(14)]
And for the 'x' list, I wanted to store the index values of the elements in 'y'. To achieve this, I tried using the code:
x = []
for i in y:
pt = y.index(i)
x.append(pt)
But when I run this, the result of the for loop ends up being:
x = [0, 1, 1, 3, 4, 5, 6, 3, 1, 9, 1, 11, 12, 13]
Why isn't the result the following?
x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
Python is returning the first location of a value in y.
Running your code, here's an example y:
[127, 124, 105, 119, 121, 118, 130, 123, 122, 105, 110, 109, 108, 110]
110 is at both 10 and 13. 105 is at both 2 and 9. Python stops looking after it finds the first one, so x then becomes:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 2, 10, 11, 12, 10]
list.index() finds the index of the first occurrence of that object in the list, which produces the results you saw when the list has repeated elements. Something like [1, 1, 1].index(1) would produce 0.
If you want to generate a list of indices, you can use list(range(len(y))), which finds the length of y, creates a range() object out of it, then creates a list out of that object. Since you're using Python 2, you can omit the list() call, since Python 2's range() will already return a list.

Sorting bytes in words, tuples in python

I looked around and I can't seem to find the proper way of sorting a 32 entry tuple by inverting every odd and even entry.
ex:
1 0 3 2 5 4 7 6 9 8
to
0 1 2 3 4 5 6 7 8 9
My current code looks like this
i=0
nd = []
while i < len(self.r.ipDeviceName):
print(i)
if i%2:
nd[i]=self.r.ipDeviceName[i-1]
else:
nd[i]=self.r.ipDeviceName[i+1]
dn = "".join(map(chr,nd))
devicenameText.SetValue(dn)
the type of self.r.ipDeviceName is tuple and I either get a IndexError or a tuple doesn't suport assignation depending on variations of the code
I also tried this with the same results
nd = self.r.ipDeviceName
for i in nd:
if i&0x01:
nd[i]=self.r.ipDeviceName[i-1]
else:
nd[i]=self.r.ipDeviceName[i+1]
dn = "".join(map(chr,nd))
devicenameText.SetValue(dn)
With the same results. Something very simple seems to elude me. Thanks for your help and time.
Tuples are immutable - you can't modify them once they are created. To modify individual elements you want to store the data in a mutable collection such as a list instead. You can use the built-in functions list and tuple to convert from tuple to list or vice versa.
Alternatively you could use zip and a functional style approach to create a new tuple from your existing tuple without modifying the original:
>>> t = tuple(range(10))
>>> tuple(x for i in zip(t[1::2], t[::2]) for x in i)
(1, 0, 3, 2, 5, 4, 7, 6, 9, 8)
Or using itertools.chain:
>>> import itertools
>>> tuple(itertools.chain(*zip(t[1::2], t[::2])))
(1, 0, 3, 2, 5, 4, 7, 6, 9, 8)
Note that the use of zip here assumes that your tuple has an even number of elements (which is the case here, according to your question).
You can't change a tuple, they're immutable. However you can replace them with a new one arranged the way you want (I wouldn't call what you want "sorted"). To do it, all that is needed it to swap each pair of items that are in the original tuple.
Here's a straight-forward implementation. Note it leaves the last entry alone if there are an odd number of them since you never said how you wanted that case handled. Dealing with that possibility complicates the code slightly.
def swap_even_odd_entries(seq):
tmp = list(seq)+[seq[-1]] # convert sequence to mutable list and dup last
for i in xrange(0, len(seq), 2):
tmp[i],tmp[i+1] = tmp[i+1],tmp[i] # swap each entry with following one
return tuple(tmp[:len(seq)]) # remove any excess
a = (1, 0, 3, 2, 5, 4, 7, 6, 9, 8)
a = swap_even_odd_entries(a)
b = (91, 70, 23, 42, 75, 14, 87, 36, 19, 80)
b = swap_even_odd_entries(b)
c = (1, 0, 3, 2, 5)
c = swap_even_odd_entries(c)
print a
print b
print c
# output
# (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
# (70, 91, 42, 23, 14, 75, 36, 87, 80, 19)
# (0, 1, 2, 3, 5)
The same thing can also be done in a less-readable way as a long single expression. Again the last entry remains unchanged if the length is odd.
swap_even_odd_entries2 = lambda t: tuple(
v for p in [(b,a) for a,b in zip(*[iter(t)]*2) + [(t[-1],)*2]]
for v in p)[:len(t)]
a = (1, 0, 3, 2, 5, 4, 7, 6, 9, 8)
a = swap_even_odd_entries2(a)
b = (91, 70, 23, 42, 75, 14, 87, 36, 19, 80)
b = swap_even_odd_entries2(b)
c = (1, 0, 3, 2, 5)
c = swap_even_odd_entries2(c)
print
print a
print b
print c
# output
# (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
# (70, 91, 42, 23, 14, 75, 36, 87, 80, 19)
# (0, 1, 2, 3, 5)
If you add the functions grouper and flatten (see itertools recipes) to your toolset, you can do:
xs = [1, 0, 3, 2, 5, 4, 7, 6, 9, 8]
xs2 = flatten((y, x) for (x, y) in grouper(2, xs))
# list(xs2) => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
You could even write flatten(imap(reversed, grouper(2, xs)) but I guess only die-hard functional guys would like it.

Categories