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
Related
I am having a scope issue, and I know how I would solve this in Java, but Python is giving me some issues. Say I have a code as follows:
a = 1
b = 2
c = 3
list1 = [a,b,c]
list2 = [b,c]
b += 1
print list1
print list2
This code does not change the value inside the lists, and there is an easy workaround for the simple example I've given, but the code I am trying to write has 10+ lists that all have different meanings and are used in different ways, but need to communicate with each other and have all the same values for a,b,c. I need to be able to change the variable a,b,c and have all the lists update as well, is there any other way besides writing out the update for each list?
You cannot store the integers by reference, such that incrementing the value in one place causes all other values to be updated. This is because ints are immutable, so changing their value causes a reference change.
>>> a = 5
>>> b = 1
>>> x = [a, b]
>>> id(b)
140508116572264
>>> id(x[1])
140508116572264
>>> b += 1
>>> id(b)
140508116572240
You can see the id of b changes after the increment, so the "b" in the loop and the "b" outside aren't the same.
What you can do, is define a wrapper class for your ints.
class MyInteger:
def __init__(self, value):
self.value = value
Now, build your lists with your MyIntegers:
a = MyInteger(1)
b = MyInteger(2)
c = MyInteger(3)
list1 = [a, b, c]
list2 = [b, c]
Now, when you increment the value of b, you can see the changes are reflected in the lists.
print([x.value for x in list1])
b.value += 1
print([x.value for x in list1])
This prints:
[1, 2, 3]
[1, 3, 3]
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 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]
Hi all im new to programming and im doing a problem for learning and enjoyment. Im a bit stuck at this point.. The problem is from Introduction to Programming using Sml 5.9
I want to split a list of [x1, x2, x3, ... ,xn] = ([x1, x3,....], [x2, x4,...])
This is what I have made so far:
fun split [] = []
| split (x1::x2::x3::x4::xs) = ([x1, x3], [x2, x4])::split xs
val test1split = split [1, 1, 2, 3];
From this I get:
[([1, 2], [1, 3])].... (I want a tuple with splitting list and not this obviously)
If there are more than 4 elements then the function doesn't work. Maybe I need a helper function to sort even and odd elements in a list first? I hope someone can help me with tracking my mind in the correct direction, until then I keep trying.
fun split [] = ([], [])
| split [x] = ([x], [])
| split (x1::x2::xs) =
let
val (ys, zs) = split xs
in
((x1::ys), (x2::zs))
end;
val test1split = split [1, 1, 2, 3, 5, 6] = ([1, 2, 5], [1, 3, 6])
val test2split = split [8, 7, 6, 5, 4, 3] = ([8, 6, 4], [7, 5, 3])
val test3split = split [8, 7] = ([8], [7])
val test4split = split [8] = ([8], [])
Solved it... Not completely sure how lol, need alot more practice to master it. Couldn't have done it without the pointers... Thx alot for the help Nick Barnes.
I'll try not to give too much away, but here are some tips:
You need two base cases - one for [], one for [x].
Your general case only needs to deal with two elements, not four (putting one in the first list, and one in the second)
At the moment, you've got split returning a list, rather than a tuple. The result of your first base case should be ([],[]).
In the general case, the recursive split xs will return a tuple (ys,zs). You need to extract these values, and build the resulting tuple in terms of ys, zs, x1 and x2.
(Edit) A couple of points on your revised solution:
You only need to deal with two elements at a time - the general case should be split x1::x2::xs
split [x,y] is handled by the general case - no need for another base case.
You're missing the recursive call! Elements are ending up in both lists because you're putting xs directly into both halves of your output - you need to split it first. Start with
let (ys, zs) = split xs in ...
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