Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a list of lists. I want to get all unique lists based on just the first three elements. If there are duplicates, then it should just return the last item. So for instance based on this
[['one', 'two', 'three', 'teennn'], ['five', 'five', 'five', 'five'],
['seven', 'nine', 'ten', 'eleven'], ['one', 'two', 'three', 'four']]
I want to return this
[['five', 'five', 'five', 'five'],
['seven', 'nine', 'ten', 'eleven'], ['one', 'two', 'three', 'four']]
lst = [['one', 'two', 'three', 'teennn'],
['five', 'five', 'five', 'five'],
['seven', 'nine', 'ten', 'eleven'],
['one', 'two', 'three', 'four']]
output = []
seen = set()
lst.reverse()
for item in lst:
if not item[:3] in seen:
output.append(item)
seen.add(item[:3])
output.reverse()
This ensures that the first three items are always unique. Starting from the end of your list lst, using reverse, ensures that the last appearance of each starting set is included.
If order isn't important, then you can use a dict:
data = [['one', 'two', 'three', 'teennn'], ['five', 'five', 'five', 'five'], ['seven', 'nine', 'ten', 'eleven'], ['one', 'two', 'three', 'four']]
new = {tuple(el[:3]): el for el in data}.values()
# [['one', 'two', 'three', 'four'], ['seven', 'nine', 'ten', 'eleven'], ['five', 'five', 'five', 'five']]
Or, if you really wanted to maintain order, then something like:
new = [data[idx] for idx in sorted({tuple(el[:3]): idx for idx, el in enumerate(data)}.values())]
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I want to looping until it meets the condition. In this case i want to continue till List_list looks like
["one","one","two","two","three","three","four","four","five","five","six","seven","eight","nine","ten"]
lst =["one","two","three","four","five","six","seven","eight","nine","ten”]
List_list = list()
for rn in lst:
List_list.append(rn)
if 15 == len(List_list):
break
Ask #2:
Solution to repeat first 5 items, then single instance of next 5 items
lst =["one","two","three","four","five","six","seven","eight","nine","ten"]
List_list = []
for i in range(10):
List_list.append(lst[i])
if i < 5:
List_list.append(lst[i])
print (List_list)
The output of this will be:
['one', 'one', 'two', 'two', 'three', 'three', 'four', 'four', 'five', 'five', 'six', 'seven', 'eight', 'nine', 'ten']
If you are looking for a single line answer using list comprehension, then you can use this.
List_list = [y for x in lst[:5] for y in [x,x]] + [x for x in lst[5:]]
print (List_list)
Output is the same:
['one', 'one', 'two', 'two', 'three', 'three', 'four', 'four', 'five', 'five', 'six', 'seven', 'eight', 'nine', 'ten']
Ask #1:
Solution for earlier question: Add 15 items to a list: All 10 items from original list + first from original list
You can do something as simple as this:
List_lst = lst + lst[:5]
print (List_lst)
If you still insist on using a for loop and you want 15 items, then do this and it will give you same output.
List_list = list()
for i in range(15):
List_list.append(lst[i%10])
print (List_list)
A list comprehension version of this will be:
List_list = [lst[i%10] for i in range(15)]
print (List_list)
If you want to fix your code with a while loop, see the details below.
Convert the for loop to while True:. Start iterating using a counter i and check for mod of 10 to get the position to be inserted.
lst = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]
List_list = list()
i = 0
while True:
List_list.append(lst[i%10])
i+=1
if len(List_list) == 15:
break
print (List_list)
This will result in
["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "one", "two", "three", "four", "five"]
This seems like a simple modulo 10 loop...
lst =["01.one","02.two","03.three","04.four","05.five","06.six","07.seven","08.eight","09.nine","10.ten"]
[w[3:] for w in sorted([lst[n%10] for n in range(15)])]
output
['one', 'one', 'two', 'two', 'three', 'three', 'four', 'four', 'five', 'five', 'six', 'seven', 'eight', 'nine', 'ten']
["one","two","three","four","five","six","seven","eight","nine","ten","one","two","three","four","five"]
lst =["one","two","three","four","five","six","seven","eight","nine","ten"]
List_list = []
length = 0
# Respect the looping statement
while length<15:
List_list.append(lst[length%10])
length+=1
print(List_list)
#Output ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'one', 'two', 'three', 'four', 'five']
EDIT 2: Complemented the answer for the updated question.
Using itertools from Python Standard Library, you can do it in three steps (steps 1 and 2 can be combined):
Use the cycle function to create an infinite iterator of the original list.
Use the islice function to get the first 15 elements from the infinite iterator.
Sort items in the resultant list by the position in the original list.
from itertools import cycle, islice
lst = ["one","two","three","four","five","six","seven","eight","nine","ten"]
infinite_lst = cycle(lst)
List_list = list(islice(infinite_lst, 15))
List_list.sort(key=lst.index)
print(List_list)
And here you have:
['one', 'one', 'two', 'two', 'three', 'three', 'four', 'four', 'five', 'five', 'six', 'seven', 'eight', 'nine', 'ten']
Use itertools.cycle:
from itertools import cycle
lst = {
"one": 1,
"two": 2,
"three": 3,
"four": 4,
"five": 5,
"six": 6,
"seven": 7,
"eight": 8,
"nine": 9,
"ten": 10
}
def get_lst(times):
output = []
for item in cycle(lst):
output.append(item)
if len(output) >= times:
break
return sorted(output, key=lambda i: lst[i])
print(get_lst(10))
-> ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten']
print(get_lst(11))
-> ['one', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten']
I agree that the second code in this answer is not more complicated as it is much easier to replicate for any other code. The best programmers create code which can be reproduced in any circumstance the best.
I have two list items and I want to generate a list based on non-matching items. Here is what I am trying to do:
from __future__ import print_function
import os
mainline_list = ['one', 'two', 'three', 'four']
non_main_list = ['two', 'seven', 'six', 'four', 'four-3.1', 'new_three']
itemized_list = [item for item in non_main_list if item not in mainline_list]
print(itemized_list)
What is returns is
['seven', 'six', 'four-3.1', 'new_three']
while what I want is:
['seven', 'six']
Regex is not necessary, you can use all() builtin function:
mainline_list = ['one', 'two', 'three', 'four']
non_main_list = ['two', 'seven', 'six', 'four', 'four-3.1', 'new_three']
print([item for item in non_main_list if all(i not in item for i in mainline_list)])
Prints:
['seven', 'six']
My main list has 44 names as elements. I want to rearrange them in a specific order. I am giving here an example. Note that elements in my actual list are some technical names. No way related to what I have given here.
main_list = ['one','two','five','six',.................'twentyone','three','four','seven','eight',.....,'fortyfour']
I want to rearrange the list. I have no idea how to proceed. But my expected output should like this
Expected output:
main_list = ['one','two','three','four','five','six','seven','eight'.................'twentyone',,.....,'fortyfour']
You can have a dictionary to use as your sorting key:
sort_keys = {
'one': 1,
'two': 2,
'three': 3,
'ten': 10,
'twenty': 20,
}
main_list = ['twenty', 'one', 'three', 'ten', 'two']
main_list.sort(key=lambda i: sort_keys[i])
print(main_list)
Output:
['one', 'two', 'three', 'ten', 'twenty']
Use something like this (this is just the first Google hit I found for something to convert English representations of numbers to integer values; whatever you use needs to be something that works to convert whatever your actual data is into something sortable): https://pypi.org/project/word2number/
from word2number import w2n
main_list.sort(key=w2n.word_to_num)
Or come up with your own cheesy version as appropriate to your data. Taking your example you could do something like:
number_words = {
'one': 1,
'two': 2,
'three': 3,
'four': 4,
'five': 5,
'six': 6,
'seven': 7,
'eight': 8,
'twenty': 20,
'forty': 40,
'sixty': 60,
}
def word_to_number(word: str) -> int:
if word in number_words:
return number_words[word]
# Try chomping each number out of the word.
for n in number_words:
if word.endswith(n):
return number_words[n] + word_to_number(word[:-len(n)])
raise ValueError(f"I don't know what number '{word}' is!")
>>> main_list
['one', 'two', 'sixtyfour', 'five', 'six', 'twentyone', 'three', 'four', 'seven', 'eight', 'fortyfour']
>>> sorted(main_list, key=word_to_number)
['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'twentyone', 'fortyfour', 'sixtyfour']
It looks like you want to sort number words in numeric order. But your examples above have poorly-formed words that need fixing, such as twentyone and fortyfour. This is one way you could address it.
from word2number import w2n
main_list = ['one', 'two', 'five', 'six', 'twentyone', 'three', 'four', 'seven', 'eight', 'fortyfour']
VALID = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen']
TENS = ['twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety']
renamed = []
for item in main_list:
if item in VALID or item in TENS:
renamed.append(w2n.word_to_num(item))
else:
for num in TENS:
one = item.split(num)[-1]
if one in VALID:
renamed.append(w2n.word_to_num(f'{num} {one}'))
Output
>>>sorted(renamed)
[1, 2, 3, 4, 5, 6, 7, 8, 21, 44]
Can anybody explain me whats wrong i am doing here -
multiArray = [
['one', 'two', 'three', 'four', 'five'],
['one', 'two', 'three', 'four', 'five'],
['one', 'two', 'three', 'four', 'five']
]
search ='four'
p1 = list(filter(lambda outerEle: search == outerEle, multiArray[0]))
p = list(filter(lambda multiArrayEle: list(filter(lambda innerArrayEle: search == innerArrayEle, multiArrayEle)), multiArray))
print (p1)
print (p)
The result i am getting here is
['four']
[['one', 'two', 'three', 'four', 'five'], ['one', 'two', 'three', 'four', 'five'], ['one', 'two', 'three', 'four', 'five']]
while i am expecting
[['four'],['four'],['four']]
In your second filter, you are using a list as a predicate (as opposed to simply a bool as you do in the first filter); now, this implicitly applies the built-in method bool to each element list, and for a list l, bool(l) is true exactly when l is non-empty:
In [4]: bool([])
Out[4]: False
In [5]: bool(['a'])
Out[5]: True
This allows you to pick out, for example, all the non-empty lists in a list of lists:
In [6]: ls = [['a'], [], ['b']]
In [7]: list(filter(lambda l: l, ls))
Out[7]: [['a'], ['b']]
Thus, in your case, at the end of the day, your filter ends up giving you all lists for which 'four' appears, which is all of them.
From your given example, it's not immediately obvious what you are trying to achieve as all the inputs are identical, but my guess is that it's something like the following:
In [19]: multiArray = [
...: ['one', 'two', 'three', 'four', 'five', 'four'],
...: ['one', 'two', 'three', 'for', 'five'],
...: ['one', 'two', 'three', 'four', 'five']
...: ]
In [20]: [list(filter(lambda x: x == search, l)) for l in multiArray]
Out[20]: [['four', 'four'], [], ['four']]
While #fuglede's answer is really the answer to your question, you can archive the result you want by changing your outer filter to map:
p = list(map(lambda multiArrayEle: list(filter(lambda innerArrayEle: search == innerArrayEle, multiArrayEle)), multiArray))
I have a list like this:
lst = [['one two', 'three'], ['four five', 'six']]
I need to make:
lst = [['one', 'two', 'three'], ['four', 'five', 'six']]
Tried
([i[0].split() for i in lst])
but it gives only
[['one', 'two'], ['four', 'five']]
Any ideas how to manage it?
Thanks in advance!
Maybe I'm oversimplifying this, but you can just join and re-split?
>>> [' '.join(x).split() for x in lst]
[['one', 'two', 'three'], ['four', 'five', 'six']]
Or, using the equivalent map method:
>>> list(map(str.split, map(' '.join, lst)))
[['one', 'two', 'three'], ['four', 'five', 'six']]