I want to know how many times a sublist is in a list next to eachother.
From another question, I received the following code to determinate if a sublist is in a list:
list_sequence = ['Example 64', 'Example 32', 'Example 16']
my_list = ['Example 128', 'Example 64', 'Example 32', 'Example 16', 'Example 256', 'Example 512', 'Example 1024']
print(str(list_sequence)[1:-1] in str(my_list))
But I want to know, how many times the list_sequence is NEXT to each other to determinate a combo. In the top example its 1, but if I would append list_sequence at the start and at the very end, it still would 1. If I would add it right after Example 16 in my_list, it would be 2.
You can use zip and enumerate within a list comprehension to find the respective indices of places where your sub_list occurs. Then select those who's subtraction is equal to 3 (length of sub_list):
In [6]: list_sequence = ['Example 64', 'Example 32', 'Example 16']
...:
...: my_list = ['Example 128', 'Example 64', 'Example 32', 'Example 16', 'Example 64', 'Example 32', 'Example 16', 'Example 256', 'Example 512', 'E
...: xample 1024','Example 64', 'Example 32', 'Example 16']
...:
In [7]: indices = [index for index, (i, j, k) in enumerate(zip(my_list, my_list[1:], my_list[2:])) if list_sequence == [i, j, k]]
Out[7]: [1, 4, 10]
In [8]: sum(2 * (j-i == len(list_sequence)) for i, j in zip(indices, indices[1:]))
Out[8]: 2
You an only use a generator expression within sum to find the number of occurrences:
In [4]: sum(list_sequence == [i, j, k] for i, j, k in zip(my_list, my_list[1:], my_list[2:]))
Out[4]: 1
But note that this will also include overlaps because zip(my_list, my_list[1:], my_list[2:])) will give you all consequent triples.
Count By creating dictionary of list_sequence
list_sequence = ['Example 64', 'Example 32', 'Example 16']
my_list = ['Example 128', 'Example 64', 'Example 32', 'Example 16','Example 16', 'Example 256', 'Example 512', 'Example 1024']
dic=dict()
for i in list_sequence :
for j in my_list :
if i==j:
dic[i]=dic.get(i,0)+1
print(dic)
{'Example 64': 1, 'Example 32': 1, 'Example 16': 2}
Related
I've got 2 lists, one with plate numbers that has duplicates in it, and the other with corresponding groups that each plate belongs to. Duplicated number means that the plate belongs to several groups. I'm trying to make a dict with the following output:
L1 = ['173', '607', '607', '581', '522', '522']
L2 = ['fleet 6', 'fleet 4', 'fleet 6', 'Toyota', 'Maintenance', 'fleet 1']
# Desirable output
# '173': 'fleet 6'
# '607': ['fleet4', 'fleet6']
# '581': 'Toyota'
# '522': ['Maintenance', 'fleet 1']
I have no clue how to cluster values as lists from L2 to match with duplicates from L1, along with singles, any ideas please?
Try this approach to see if that help. It's only one way to solve it, prob. easy to understand.
from collections import defaultdict
from pprint import pprint
L1 = ['173', '607', '607', '581', '522', '522']
L2 = ['fleet 6', 'fleet 4', 'fleet 6', 'Toyota', 'Maintenance', 'fleet 1']
# Desirable output
# '173': 'fleet 6'
# '607': ['fleet4', 'fleet6']
# '581': 'Toyota'
# '522': ['Maintenance', 'fleet 1']
dc = defaultdict(list)
for i in range(len(L1)):
item = L1[i]
dc[item].append(L2[i])
pprint(dc)
Edit:
As #KellyBundy suggests, you could use this more pythonic way to solve it too:
dc = defaultdict(list)
for item, plate in zip(L1, L2):
dc[item].append(plate)
pprint(dc)
Try the following:
d = {}
L1 = ['173', '607', '607', '581', '522', '522']
L2 = ['fleet 6', 'fleet 4', 'fleet 6', 'Toyota', 'Maintenance', 'fleet 1']
for l1, l2 in zip(L1, L2):
d[l1] = d.get(l1, [])
d[l1].append(l2)
Where the d.get() function gets the item and if the key does not exist returns an empty list
Using setdefault:
d = {}
for k, v in zip(L1, L2):
d.setdefault(k, []).append(v)
print(d)
#{'173': ['fleet 6'], '607': ['fleet 4', 'fleet 6'], '581': ['Toyota'], '522': ['Maintenance', 'fleet 1']}
You can make this:
result = {key: [] for key in L1}
for i, value in enumerate(L2):
result[L1[i]].append(value)
Simple and quick!
Steps
Create and dict with all keys of L1 and an empty list in value
Add the value of L2 (know the key by the index on enumerate)
I am having trouble understanding key parameter in sorted function in Python.
Let us say, the following list is given: sample_list = ['Date ', 'of', 'birth', 'year 1990', 'month 10', 'day 15'] and I would like to sort only the strings that contain number.
Expected output: ['Date ', 'of', 'birth', 'month 10', 'day 15', 'year 1990']
Until now, I only managed to print the string with the number
def sort_with_key(element_of_list):
if re.search('\d+', element_of_list):
print(element_of_list)
return element_of_list
sorted(sample_list, key = sort_with_key)
But how do I actually sort those elements?
Thank you!
We can try sorting with a lambda:
sample_list = ['Date ', 'of', 'birth', 'year 1990', 'month 10', 'day 15']
sample_list = sorted(sample_list, key=lambda x: int(re.findall(r'\d+', x)[0]) if re.search(r'\d+', x) else 0)
print(sample_list)
This prints:
['Date ', 'of', 'birth', 'month 10', 'day 15', 'year 1990']
The logic used in the lambda is to sort by the number in each list entry, if the entry has a number. Otherwise, it assigns a value of zero to other entries, placing them first in the sort.
If I understand correctly, you want strings with a number to be sorted with this number as key, and strings without a number to be at the beginning?
You need a key that extracts the number from the string. We can use str.isdigit() to extract digits from a string, ''.join() to put these digits back together, and int() to convert to an integer. If there are no digits in the string, we'll return -1 instead, so it comes before all nonnegative numbers.
sample_list = ['Date ', 'of', 'birth', 'year 1990', 'month 10', 'day 15', 'answer 42', 'small number 0', 'large number 8676965', 'no number here']
sample_list.sort(key=lambda s: int(''.join(c for c in s if c.isdigit()) or -1))
print(sample_list)
# ['Date ', 'of', 'birth', 'no number here', 'small number 0', 'month 10', 'day 15', 'answer 42', 'year 1990', 'large number 8676965']
I have a nested loop that follows as below
arr = [[' item 1 ', 'item 2 ', 'item 3'], ['item 4 ', 'item 5', 'item 6'], ['item 7 ', 'item 8', 'item 9' ]]
I am trying to loop through the arr with 2 for loops to get rid of (strip) the spaces around each item in the inner loop. But when I use the following code, although I can get rid of the spaces, the final result only forms a combined list without the inner list elements intact.
clean_arr = []
for i in arr:
for j in i:
clean_arr.append(j.strip(' '))
The result I get is a single list without any inner lists/nested lists. But what I want is to keep the exact nested structure.
How can I achieve the result? Could you please put some discussion as well. Thanks
Try a list comprehension as follows:
clean_arr = [[y.strip() for y in x] for x in arr]
print(clean_arr)
Output:
[['item 1', 'item 2', 'item 3'], ['item 4', 'item 5', 'item 6'], ['item 7', 'item 8', 'item 9']]
If you want to use a for loop, try the below code:
clean_arr = []
for i in arr:
l = []
for j in i:
l.append(j.strip())
clean_arr.append(l)
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have an array that contains numbers and characters, e.g. ['A 3', 'C 1', 'B 2'], and I want to sort it using the numbers in each element.
I tried the below code but it did not work
def getKey(item):
item.split(' ')
return item[1]
x = ['A 3', 'C 1', 'B 2']
print sorted(x, key=getKey(x))
To be safe, I'd recommend you to strip everything but the digits.
>>> import re
>>> x = ['A 3', 'C 1', 'B 2', 'E']
>>> print sorted(x, key=lambda n: int(re.sub(r'\D', '', n) or 0))
['E', 'C 1', 'B 2', 'A 3']
With your method;
def getKey(item):
return int(re.sub(r'\D', '', item) or 0)
>>> print sorted(x, key=getKey)
['E', 'C 1', 'B 2', 'A 3']
What you have, plus comments to what's not working :P
def getKey(item):
item.split(' ') #without assigning to anything? This doesn't change item.
#Also, split() splits by whitespace naturally.
return item[1] #returns a string, which will not sort correctly
x = ['A 3', 'C 1', 'B 2']
print sorted(x, key=getKey(x)) #you are assign key to the result of getKey(x), which is nonsensical.
What it should be
print sorted(x, key=lambda i: int(i.split()[1]))
This is one way to do it:
>>> x = ['A 3', 'C 1', 'B 2']
>>> y = [i[::-1] for i in sorted(x)]
>>> y.sort()
>>> y = [i[::-1] for i in y]
>>> y
['C 1', 'B 2', 'A 3']
>>>
If I have a list of strings (eg 'blah 1', 'blah 2' 'xyz fg','xyz penguin'), what would be the best way of finding the unique starts of strings ('xyz' and 'blah' in this case)? The starts of strings can be multiple words.
Your question is confusing, as it is not clear what you really want. So I'll give three answers and hope that one of them at least partially answers your question.
To get all unique prefixes of a given list of string, you can do:
>>> l = ['blah 1', 'blah 2', 'xyz fg', 'xyz penguin']
>>> set(s[:i] for s in l for i in range(len(s) + 1))
{'', 'xyz pe', 'xyz penguin', 'b', 'xyz fg', 'xyz peng', 'xyz pengui', 'bl', 'blah 2', 'blah 1', 'blah', 'xyz f', 'xy', 'xyz pengu', 'xyz p', 'x', 'blah ', 'xyz pen', 'bla', 'xyz', 'xyz '}
This code generates all initial slices of every string in the list and passes these to a set to remove duplicates.
To get all largest initial word sequences smaller than the full string, you could go with:
>>> l = ['a b', 'a c', 'a b c', 'b c']
>>> set(s.rsplit(' ', 1)[0] for s in l)
{'a', 'a b', 'b'}
This code creates a set by splitting all strings at their rightmost space, if available (otherwise the while string will be returned).
On the other hand, to get all unique initial word sequences without considering full strings, you could go for:
>>> l = ['a b', 'a c', 'a b c', 'b c']
>>> set(' '.join(w[:i]) for s in l for w in (s.split(),) for i in range(len(w)))
{'', 'a', 'b', 'a b'}
This code splits each word at any whitespace and concatenates all initial slices of the resulting list, except the largest one. This code has pitfall: it will e.g. convert tabs to spaces. This may or may not be an issue in your case.
If you mean unique first words of strings (words being separated by space), this would be:
arr=['blah 1', 'blah 2' 'xyz fg','xyz penguin']
unique=list(set([x.split(' ')[0] for x in arr]))