Create two lists from list of tuples - python

I want to create two lists based on sorted_bounds with every other tuple.
bounds = [1078.08, 1078.816, 1078.924, 1079.348, 1079.448, 1079.476]
sorted_bounds = list(zip(bounds,bounds[1:]))
print(sorted_bounds)
# -> [(1078.08, 1078.816), (1078.816, 1078.924), (1078.924, 1079.348), (1079.348, 1079.448), (1079.448, 1079.476)]
Desired output:
list1 = [(1078.08, 1078.816), (1078.924, 1079.348), (1079.448, 1079.476)]
list2 = [(1078.816, 1078.924), (1079.348, 1079.448)]
How would I do this? I am completely blanking.

list1 = sorted_bounds[0::2]
list2 = sorted_bounds[1::2]
The third value in brackets is "step", so every second element in this case.

Trying to think of a way of doing this in a single pass, but here's a clean way to do it in two passes:
list1 = [x for i, x in enumerate(sorted_bounds) if not i % 2]
list2 = [x for i, x in enumerate(sorted_bounds) if i % 2]
print(list1)
print(list2)
Result:
[(1078.08, 1078.816), (1078.924, 1079.348), (1079.448, 1079.476)]
[(1078.816, 1078.924), (1079.348, 1079.448)]

Related

concentrate 2 lists in python based on a shared substring

I have two lists, for example they look something like this:
list1 = ["Time1Person001", "Time1Person002", "Time1Person003", "Time1Person004", "Time1Person005"]
list2 = ["Time2Person001", "Time2Person003", "Time2Person004", "Time2Person007"]
I want to create a third list that contains only strings that share a substring of the last 3 charachters, so the output should be:
list3 = ["Time1Person001", "Time1Person003", "Time1Person004", "Time2Person001", "Time2Person003", "Time2Person004"]
Efficient way to do it?
Thanks!
Create a set of the common endings then filter each list by that set.
list1 = ["Time1Person001", "Time1Person002", "Time1Person003", "Time1Person004", "Time1Person005"]
list2 = ["Time2Person001", "Time2Person003", "Time2Person004", "Time2Person007"]
endings = set(v[-3:] for v in list1) & set(v[-3:] for v in list2)
list3 = [v for v in list1+list2 if v[-3:] in endings]
Is this what you're after:
list3 = [x for x in list1 for y in list2 if x[-3:] == y[-3:]]

Easier way to check if an item from one list of tuples doesn't exist in another list of tuples in python

I have two lists of tuples, say,
list1 = [('item1',),('item2',),('item3',), ('item4',)] # Contains just one item per tuple
list2 = [('item1', 'd',),('item2', 'a',),('item3', 'f',)] # Contains multiple items per tuple
Expected output: 'item4' # Item that doesn't exist in list2
As shown in above example I want to check which item in tuples in list 1 does not exist in first index of tuples in list 2. What is the easiest way to do this without running two for loops?
Assuming your tuple structure is exactly as shown above, this would work:
tuple(set(x[0] for x in list1) - set(x[0] for x in list2))
or per #don't talk just code, better as set comprehensions:
tuple({x[0] for x in list1} - {x[0] for x in list2})
result:
('item4',)
This gives you {'item4'}:
next(zip(*list1)) - dict(list2).keys()
The next(zip(*list1)) gives you the tuple ('item1', 'item2', 'item3', 'item4').
The dict(list2).keys() gives you dict_keys(['item1', 'item2', 'item3']), which happily offers you set operations like that set difference.
Try it online!
This is the only way I can think of doing it, not sure if it helps though. I removed the commas in the items in list1 because I don't see why they are there and it affects the code.
list1 = [('item1'),('item2'),('item3'), ('item4')] # Contains just one item per tuple
list2 = [('item1', 'd',),('item2', 'a',),('item3', 'f',)] # Contains multiple items per tuple
not_in_tuple = []
OutputTuple = [(a) for a, b in list2]
for i in list1:
if i in OutputTuple:
pass
else:
not_in_tuple.append(i)
for i in not_in_tuple:
print(i)
You don't really have a choice but to loop over the two lists. Once efficient way could be to first construct a set of the first elements of list2:
items = {e[0] for e in list2}
list3 = list(filter(lambda x:x[0] not in items, list1))
Output:
>>> list3
[('item4',)]
Try set.difference:
>>> set(next(zip(*list1))).difference(dict(list2))
{'item4'}
>>>
Or even better:
>>> set(list1) ^ {x[:1] for x in list2}
{('item4',)}
>>>
that is a difference operation for sets:
set1 = set(j[0] for j in list1)
set2 = set(j[0] for j in list2)
result = set1.difference(set2)
output:
{'item4'}
for i in list1:
a=i[0]
for j in list2:
b=j[0]
if a==b:
break
else:
print(a)

Python trouble with matching tuples

For reference this is my code:
list1 = [('10.180.13.101', '10.50.60.30', 'STCMGMTUNIX01')]
list2 = [('0.0.0.0', 'STCMGMTUNIX01')]
for i in list1:
for j in list2:
for k in j:
print (k)
if k.upper() in i:
matching_app.add(j)
for i in matching_app:
print (i)
When I run it, it does not match. This list can contain two or three variables and I need it to add it to the matching_app set if ANY value from list2 = ANY value from list1. It does not work unless the tuples are of equal length.
Any direction to how to resolve this logic error will be appreciated.
You can solve this in a few different ways. Here are two approaches:
Looping:
list1 = [('10.180.13.101', '10.50.60.30', 'STCMGMTUNIX01')]
list2 = [('0.0.0.0', 'STCMGMTUNIX01')]
matches = []
for i in list1[0]:
if i in list2[0]:
matches.append(i)
print(matches)
#['STCMGMTUNIX01']
List Comp with a set
merged = list(list1[0] + list2[0])
matches2 = set([i for i in merged if merged.count(i) > 1])
print(matches2)
#{'STCMGMTUNIX01'}
I'm not clear of what you want to do. You have two lists, each containing exactly one tuple. There also seems to be one missing comma in the first tuple.
For finding an item from a list in another list you can:
list1 = ['10.180.13.101', '10.50.60.30', 'STCMGMTUNIX01']
list2 = ['0.0.0.0', 'STCMGMTUNIX01']
for item in list2:
if item.upper() in list1: # Check if item is in list
print(item, 'found in', list1)
Works the same way with tuples.

Pop a largest number in a list to another list, python

I want to get the max() nubmer in a list and then pop it to another list, (list1).
x = [66,1,4,3,6,55]
list1 = []
for i in x:
x.pop(max(x))
#poped item saved to list1
print(list1)
This is my approach but i get the error " pop index out of range". What am i doing wrong ? And i really dont know how to further pop() an item and return it to an empty list.The result should be a list1 with numbers from highest to lowest. Please, dont post any other algorithm with built in functions like sort(). Thanks.
You need to provide the index of the max element in a list to pop
x = [66,1,4,3,6,55]
list1 = [x.pop(x.index(max(x)))]
print(list1)
Output
[66]
Request from Comments:
x = [66,1,4,3,6,55]
list1 = []
while x:
list1.append(x.pop(x.index(max(x))))
print(list1)
In python pop method's argument is index, But you are passing values.
x = [66,1,4,3,6,55]
list1 = []
for i in range(len(x)):
list1.append(x.pop(x.index(max(x))))
print(list1)
Try this.
You can try:
>>> x = [66,1,4,3,6,55]
>>> list_popped = []
>>> list_popped.append(x.pop(x.index(max(x))))
>>> print list_popped
[66]
>>> print x
[1, 4, 3, 6, 55]
List pop method takes index of the element as argument. you are providing the item itself. In your example the first value will be 66 and you are trying pop(66), there is no item at 66th index(the length of the list is less than 66).
try the following code
x = [66,1,4,3,6,55]
list1 = []
for i in range(len(x)):
max_val = max(x)
max_val_index = x.index(max_val)
list1.append(max_val)
x.pop(max_val_index)
print(list1)
Output: [66, 55, 6, 4, 3, 1]

Finding indices of items from a list in another list even if they repeat

This answer works very well for finding indices of items from a list in another list, but the problem with it is, it only gives them once. However, I would like my list of indices to have the same length as the searched for list.
Here is an example:
thelist = ['A','B','C','D','E'] # the list whose indices I want
Mylist = ['B','C','B','E'] # my list of values that I am searching in the other list
ilist = [i for i, x in enumerate(thelist) if any(thing in x for thing in Mylist)]
With this solution, ilist = [1,2,4] but what I want is ilist = [1,2,1,4] so that len(ilist) = len(Mylist). It leaves out the index that has already been found, but if my items repeat in the list, it will not give me the duplicates.
thelist = ['A','B','C','D','E']
Mylist = ['B','C','B','E']
ilist = [thelist.index(x) for x in Mylist]
print(ilist) # [1, 2, 1, 4]
Basically, "for each element of Mylist, get its position in thelist."
This assumes that every element in Mylist exists in thelist. If the element occurs in thelist more than once, it takes the first location.
UPDATE
For substrings:
thelist = ['A','boB','C','D','E']
Mylist = ['B','C','B','E']
ilist = [next(i for i, y in enumerate(thelist) if x in y) for x in Mylist]
print(ilist) # [1, 2, 1, 4]
UPDATE 2
Here's a version that does substrings in the other direction using the example in the comments below:
thelist = ['A','B','C','D','E']
Mylist = ['Boo','Cup','Bee','Eerr','Cool','Aah']
ilist = [next(i for i, y in enumerate(thelist) if y in x) for x in Mylist]
print(ilist) # [1, 2, 1, 4, 2, 0]
Below code would work
ilist = [ theList.index(i) for i in MyList ]
Make a reverse lookup from strings to indices:
string_indices = {c: i for i, c in enumerate(thelist)}
ilist = [string_indices[c] for c in Mylist]
This avoids the quadratic behaviour of repeated .index() lookups.
If you data can be implicitly converted to ndarray, as your example implies, you could use numpy_indexed (disclaimer: I am its author), to perform this kind of operation in an efficient (fully vectorized and NlogN) manner.
import numpy_indexed as npi
ilist = npi.indices(thelist, Mylist)
npi.indices is essentially the array-generalization of list.index. Also, it has a kwarg to give you control over how to deal with missing values and such.

Categories