I have two lists that I need to merge into a new list, but the new list needs to contain merged indexes of the original lists. For example:
List1 = [1, 2, 3]
List2 = [a, b, c]
I need the output to be:
finalList = [1a, 2b, 3c]
I need to be able to do this in groovy. I appreciate any help you can provide.
Assuming both lists are the same size, in Groovy 2.4+,
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
assert ['1a', '2b', '3c'] == list1.withIndex().collect { it, index -> it + list2[index] }
Alternatively and a bit more simply in Groovy 1.5+,
assert ['1a', '2b', '3c'] == [list1, list2].transpose()*.sum()
The following is very close to doelleri's solution:
In Groovy 2.4+
println ([list1, list2].transpose().collect{it -> it[0] + it[1]})
OUTPUT
[1a, 2b, 3c]
Related
I am stuck on a problem involving adding two lists together.
For example, if list1 was [1,2,3,4] and list2 was [2,4] I would have to return [3,5,3,4]. Or if list1=[0] and list2=[1] I would return [1]
def addsum(list1,list2):
new_list = []
list1[0]+list2[0] = new_list[0]
and so on. This was my first approach but I'm getting a lot of errors. I'm new to lists so I can't use index or lambda functions. I am only allowed to use len(). Would appreciate the help.
You may want to check out 2 python concepts: list comprehension (http://www.secnetix.de/olli/Python/list_comprehensions.hawk) and condensed form of if-else (https://stackoverflow.com/a/2802748/1045285).
l1 = [1, 2, 4, 5]
l2 = [2, 4]
min_len = min(len(l1), len(l2))
rem = l1[min_len:] if len(l1) > len(l2) else l2[min_len:]
res = [e1 + e2 for e1, e2 in zip(l1[:min_len], l2[:min_len])] + rem
If I have an input like this (1, 2, 3, 4, 5, 6)
The output has to be ... [[1, 2], [3, 4], [5, 6]].
I know how to deal with if it's one element but not two.
x=[]
for number in numbers:
x.append([number])
I'll appreciate your any help!
Something like this would work:
out = []
lst = (1,2,3,4,5,6,7,8,9,10)
for x in range(len(lst)):
if x % 2 == 0:
out.append([lst[x], lst[x+1]])
else:
continue
To use this, just set lst equal to whatever list of numbers you want. The final product is stored in out.
There is a shorter way of doing what you want:
result = []
L = (1,2,3,4,5,6,7,8,9,10)
result = [[L[i], L[i + 1]] for i in range(0, len(L) - 1, 2)]
print(result)
You can use something like this. This solution also works for list of odd length
def func(lst):
res = []
# Go through every 2nd value | 0, 2, 4, ...
for i in range(0, len(lst), 2):
# Append a slice of the list, + 2 to include the next value
res.append(lst[i : i + 2])
return res
# Output
>>> lst = [1, 2, 3, 4, 5, 6]
>>> func(lst)
[[1, 2], [3, 4], [5, 6]]
>>> lst2 = [1, 2, 3, 4, 5, 6, 7]
>>> func(lst2)
[[1, 2], [3, 4], [5, 6], [7]]
List comprehension solution
def func(lst):
return [lst[i:i+2] for i in range(0, len(lst), 2)]
Slicing is better in this case as you don't have to account for IndexError allowing it to work for odd length as well.
If you want you can also add another parameter to let you specify the desired number of inner elements.
def func(lst, size = 2): # default of 2 it none specified
return [lst[i:i+size] for i in range(0, len(lst), size)]
There's a few hurdles in this problem. You want to iterate through the list without going past the end of the list and you need to deal with the case that list has an odd length. Here's one solution that works:
def foo(lst):
result = [[x,y] for [x,y] in zip(lst[0::2], lst[1::2])]
return result
In case this seems convoluted, let's break the code down.
Index slicing:
lst[0::2] iterates through lst by starting at the 0th element and proceeds in increments of 2. Similarly lst[1::2] iterates through starting at the 1st element (colloquially the second element) and continues in increments of 2.
Example:
>>> lst = (1,2,3,4,5,6,7)
>>> print(lst[0::2])
(1,3,5,7)
>>> print(lst[1::2])
(2,4,6)
zip: zip() takes two lists (or any iterable object for that matter) and returns a list containing tuples. Example:
>>> lst1 = (10,20,30, 40)
>>> lst2 = (15,25,35)
>>> prit(zip(lst1, lst2))
[(10,15), (20,25), (30,35)]
Notice that zip(lst1, lst2) has the nice property that if one of it's arguments is longer than the other, zip() stops zipping whenever the shortest iterable is out of items.
List comprehension: python allows iteration quite generally. Consider the statement:
>>> [[x,y] for [x,y] in zip(lst1,lst2)]
The interior bit "for [x,y] in zip(lst1,lst2)" says "iterate through all pairs of values in zip, and give their values to x and y". In the rest of the statement
"[[x,y] for [x,y] ...]", it says "for each set of values x and y takes on, make a list [x,y] to be stored in a larger list". Once this statement executes, you have a list of lists, where the interior lists are all possible pairs for zip(lst1,lst2)
Very Clear solution:
l = (1, 2, 3, 4, 5, 6)
l = iter(l)
w = []
for i in l:
sub = []
sub.append(i)
sub.append(next(l))
w.append(sub)
print w
i searched for a solution to remove deplicates from two 2d list in python i couldn't find so here my question:
i have two lists, for example
[[1,2],[3,5],[4,4],[5,7]]
[[1,3],[4,4],[3,5],[3,5],[5,6]]
Expected result:
[[1,2],[1,3],[5,7],[5,6]]
I want to remove list inside on the lists that match EXACTLY the values of the other list.
my script:
def filter2dim(firstarray, secondarray):
unique = []
for i in range(len(firstarray)):
temp=firstarray[i]
for j in range(len(secondarray)):
if(temp == secondarray[j]):
break
elif(j==(len(secondarray)-1)):
unique.append(temp)
for i in range(len(secondarray)):
temp=secondarray[i]
for j in range(len(firstarray)):
if(temp == firstarray[j]):
break
elif(j==(len(firstarray)-1)):
unique.append(secondarray[i])
return
Please if you fix it and explain what you did it will be greateful.
Thank you, Best Regards
Replace your 2-item lists with tuples and you can use set operations (because tuples are immutable and lists not, and set items must be immutable):
a = {(1,2),(3,5),(4,4),(5,7)}
b = {(1,3),(4,4),(3,5),(3,5),(5,6)}
print(a.symmetric_difference(b)) # {(1, 2), (5, 7), (5, 6), (1, 3)}
Note this also removes duplicates within each list because they are sets, and order is ignored.
If you need to programatically convert your lists into tuples, a list comprehension works just fine:
list_a = [[1,2],[3,5],[4,4],[5,7]]
set_a = {(i, j) for i, j in list_a}
print(set_a) # {(1, 2), (4, 4), (5, 7), (3, 5)}
Your script works fine for me, just add: return unique
Turn the first list into a dict:
a = [[1, 2], [3, 5], [4, 4], [5, 7]]
b = [[1, 3], [4, 4], [3, 5], [3, 5], [5, 6]]
filt = dict(a)
result = [el for el in b if el[0] in filt and el[0] == filt[el[0]]]
Alternatively, turn the first list into a set of tuples, and just check for membership:
filt = set(map(tuple, a))
result = [el for el in b if tuple(el) in filt]
Both of these solutions avoid iterating through the first list more than once, because dict and set lookups are O(1).
I found some Vim list functions can not work as I thought.
For example:
let list0 = [1, [1, 2]]
echo count(list0, 1)
It returns 1, but I want it returns 2. So I think those functions can not deep into nested lists, only work on first level.
I think here I should expand nested list into a normal list like this:
list0 = [1, 1, 2]
How to flatten a nested list?
" Code from bairui##vim.freenode
" https://gist.github.com/3322468
function! Flatten(list)
let val = []
for elem in a:list
if type(elem) == type([])
call extend(val, Flatten(elem))
else
call add(val, elem)
endif
unlet elem
endfor
return val
endfunction
Here unlet elem is necessary. Because the elem variable is changing, it is a list item, or a list, and VimL does not support assign a list item to a list, and vice versa.
You can use reduce() since 8.2.0878:
let mylist = [[1, 2], [3, 4], 5]
echo reduce(mylist, { acc, val -> type(val) == 3 ? extend(acc, val) : add(acc, val)})
outputs:
[1, 2, 3, 4, 5]
I suggest vital.vim's Data.List.flatten as an another answer ;D
https://github.com/vim-jp/vital.vim
I'm trying to understand how comprehensions work.
I would like to loop through two lists, and compare each to find differences.
If one/or-more word(s) is different, I would like to print this word(s).
I'd like this all in one nice line of code, which is why I'm interested in comprehensions.
Doing it in "one nice line of code" is code golf, and misguided. Make it readable instead.
for a, b in zip(list1, list2):
if a != b:
print(a, "is different from", b)
This is not different in any significant way from this:
[print(a, "is different from", b) for a, b in zip(list1, list2) if a!=b]
Except that the expanded version easier to read and understand than the comprehension.
Like kriegar suggested using sets is probably the easiest solution. If you absolutely need to use list comprehension, I'd use something like this:
list_1 = [1, 2, 3, 4, 5, 6]
list_2 = [1, 2, 3, 0, 5, 6]
# Print all items from list_1 that are not in list_2 ()
print(*[item for item in list_1 if item not in list_2], sep='\n')
# Print all items from list_1 that differ from the item at the same index in list_2
print(*[x for x, y in zip(list_1, list_2) if x != y], sep='\n')
# Print all items from list_2 that differ from the item at the same index in list_1
print(*[y for x, y in zip(list_1, list_2) if x != y], sep='\n')
If you want to compare two lists for differences, I think you want to use a set.
s.symmetric_difference(t) s ^ t new set with elements in either s or t but not both
example:
>>> L1 = ['a', 'b', 'c', 'd']
>>> L2 = ['b', 'c', 'd', 'e']
>>> S1 = set(L1)
>>> S2 = set(L2)
>>> difference = list(S1.symmetric_difference(S2))
>>> print difference
['a', 'e']
>>>
one-line form?
>>> print list(set(L1).symmetric_difference(set(L2)))
['a', 'e']
>>>
if you really want to use a list comprehension:
>>> [word for word in L1 if word not in L2] + [word for word in L2 if word not in L1]
['a', 'e']
much less efficient as the size of the lists grow.