I'm doing a code that needs to store the values of the inputs in two arrays. I'm gonna do a example.
INPUTS: 1,2,3,4,5,6,7,8
Array1= []
Array2= []
What I want to make is store the first value of the input in the array1 and the second in the array2. The final result will be this
Array1=[1,3,5,7]
Array2=[2,4,6,8]
Is possible to do that in python3? Thank you
I tried something like this but doesn't work
arr1,arr2 = list(map(int, input().split()))
You can use the following:
l = [int(x) for x in input().split(',')]
array_1 = l[::2]
array_2 = l[1::2]
So, I assume that you can get the inputs into a list or 'array' using the split? It would be nice to somehow 'map' the values, and numpy probably would offer a good solution. Though, here is a straight forward work;
while INPUTS:
ARRAY1.append(INPUTS.pop())
if INPUTS:
ARRAY2.append(INPUTS.pop())
your attempt:
arr1,arr2 = list(map(int, input().split()))
is trying to unpack evenly a list of 8 elements in 2 elements. Python can unpack 2 elements into 1 or 2, or even use iterable unpacking like:
>>> arr1,*arr2 = [1,2,3,4]
>>> arr2
[2, 3, 4]
but as you see the result isn't what you want.
Instead of unpacking, use a list of lists, and a modulo to compute the proper destination, in a loop:
lst = list(range(1,9)) # or list(map(int, input().split())) in interactive string mode
arrays = [[],[]]
for element in lst:
arrays[element%2].append(element)
result:
[[2, 4, 6, 8], [1, 3, 5, 7]]
(change the order with arrays[1-element%2])
The general case would be to yield the index depending on a condition:
arrays[0 if some_condition(element) else 1].append(element)
or with 2 list variables:
(array1 if some_condition(element) else array2).append(element)
There is my solution in a Class ;)
class AlternateList:
def __init__(self):
self._aList = [[],[]]
self._length = 0
def getItem(self, index):
listSelection = int(index) % 2
if listSelection == 0:
return self._aList[listSelection][int(index / 2)]
else:
return self._aList[listSelection][int((index -1) / 2)]
def append(self, item):
# select list (array) calculating the mod 2 of the actual length.
# This alternate between 0 and 1 depending if the length is even or odd
self._aList[int(self._length % 2)].append(item)
self._length += 1
def toList(self):
return self._aList
# add more methods like pop, slice, etc
How to use:
inputs = ['lemon', 'apple', 'banana', 'orange']
aList = AlternateList()
for i in inputs:
aList.append(i)
print(aList.toList()[0]) # prints -> ['lemon', 'banana']
print(aList.toList()[1]) # prints -> ['apple', 'orange']
print(aList.getItem(3)) # prints -> "orange" (it follow append order)
The pythonic way
Here I have taken some assumptions according to above question:
Given inputs only contain integers.
odd and even are two arrays which contain odd numbers and even numbers respectively.
odd, even = list(), list()
[even.append(i) if i % 2 == 0 else odd.append(i) for i in list(map(int, input().split()))]
print("Even: {}".format(even))
print("Odd: {}".format(odd))
Related
The task I have is as shown. Given two lists of ints, such as:
lst1 = [4,1,3,5,2]
lst2 = [1,3,5,2,4]
I want to get the mean of the ints indexes. For example, the int 4 will have indexes of 0 and 3, thus will have an index mean of 1.5. Similarly, int 1 will have an index mean of 1. I want to then have all ints in a list, sorted by their 'index mean'. The result should be:
result = [1, 3, 4, 5, 2]
as their means are 0.5, 1.5, 2, 2.5, and 3.5, respectively.
What is a fast pythonic way of doing this without going through some complicated iterations? All help is appreciated!
>>> lst1 = [4,1,3,5,2]
>>> lst2 = [1,3,5,2,4]
>>> sorted(lst1, key=lambda n: lst1.index(n) + lst2.index(n))
[1, 3, 4, 5, 2]
Note that finding the actual average (i.e. dividing the sum by 2) isn't necessary since you're using the values as sort keys; as long as they have the same comparison results as the averages (which they will since each sum is the average times a constant factor of 2) you get the correct result.
For a more efficient solution, you'd build a dictionary so you only need to iterate through each list once to sum up all the indices:
>>> avg_indices = {n: 0 for n in lst1}
>>> for a in (lst1, lst2):
... for i, n in enumerate(a):
... avg_indices[n] += i
...
>>> sorted(lst1, key=avg_indices.get)
[1, 3, 4, 5, 2]
Building lists of indices (and taking the actual average) would become necessary if you didn't have the same number of occurrences of each item across the lists.
So there are probably multiple ways, and it all depends on the lists you are working on. Here are two examples:
lst1 = [4,1,3,5,2]
lst2 = [1,3,5,2,4]
means = []
for i in range(len(lst1)):
i2 = lst2.index(lst1[i])
means.append(math.round((i+i2)/2))
print(means)
Another way is to use a generator function:
def indexmeans(a,b):
for i in range(len(a)):
i2 = b.index(a[i])
yield math.round((i+i2)/2)
lst1 = [4,1,3,5,2]
lst2 = [1,3,5,2,4]
print(list(indexmeans(lst1, lst2)))
If you want to support lists with mismatched number of elements, handle if one value is not part of the other list and so on, you have to add the logic to handle that to suit your application.
I have two lists,
In the first list I have all the information:
list1 = ['node1=6d', 'node2=10d', 'node3=5d']
In the second I just have the days:
list 2 = [6, 10, 5]
Is there a way to take the position from the indexes of the second one, that are <=7 ? (For example) and then print those with the same position of the list1?
Example:
Values of list2 that are <= 7:
Position 0, 2
Then print from list one those values with the position 0, 2
Output should be:
['node1=6d', 'node3=5d']
Original answer:
from operator import itemgetter
idx = [i for i, n in enumerate(list2) if n <= 7]
result = itemgetter(*idx)(list1)
print(result)
To get the list item indices according to a condition, you can just use a list comprehension:
idx = [i for i, n in enumerate(list2) if n <= 7]
If you wish to retrieve the values using the indices, you have several options, some of which are:
Using itemgetter:
Return a callable object that fetches item from its operand using the operand’s getitem() method. If multiple items are specified, returns a tuple of lookup values.
[Python Documentation]
from operator import itemgetter
result = itemgetter(*idx)(list1)
print(result)
('node1=6d', 'node3=5d')
Using a list comprehension again:
result = [list1[i] for i in idx]
Directly invoking __getitem__ (This is not a best practice!):
Called to implement evaluation of self[key]...
[Python Documentation]
result = list(map(list1.__getitem__, idx))
Bonus: If you wish to use numpy at some point, this would be a convenient solution:
import numpy as np
# Creating numpy arrays
list1 = np.array(['node1=6d', 'node2=10d', 'node3=5d'])
list2 = np.array([6, 10, 5])
# Getting the indices
idx = np.where(list2 <= 7)
# Getting all the values at once and converting the array into a list
result = list(list1[idx])
You can try this:
days_condition = 7
index_output = [index for index,val in enumerate(list_2) if val<=days_condition]
"Positions: "+",".join(map(str, index_output))
## you can access the list1 using the index_output
[list1[index] for index in index_output]
output:
'Positions 0,2'
['node1=6d', 'node3=5d']
You can use zip()
res = [x for x, y in zip(list1, list2) if y < 8]
print(res)
#['node1=6d', 'node3=5d']
What I want to do is to choose one item in list A and another one in list B, pair them like:
A[0]+B[n], A[1]+B[n-1],.....,A[n]+B[1]
I use two for loops but it doesn't work:
class Solution(object):
def plusOne(self, digits):
sum=0
for j in range(len(digits)-1,0,-1) :
for i in range(0,len(digits),1):
sum=sum+digits[i]*pow(10,j)
return sum+1
I inputted [1,2,3] and what I want to get is 124,
but I got 661.
Edit:
Sorry, the example I gave above is not so clear.
Let us think about A[1,2,3] and B[6,5,4].
I want output [5,7,9], because 5 is 1+4, 7 is 2+5, 9 is 3+6
What you are trying to do is turn a list of digits into the according number (and add 1). You can enumerate the reversed list in order to pair a digit with its appropriate power of 10:
digits = [1, 2, 3]
sum(10**i * y for i, y in enumerate(digits[::-1])) + 1
# 124
You can apply that to your other example as follows, using zip:
A = [1,2,3]
B = [6,5,4]
sum(10**i * (x+y) for i, (x, y) in enumerate(zip(B, A[::-1])))
# 579
You can do this without a loop:
A = [1,2,3]
B = [6,5,4]
C = list(map(sum,zip(A,B[::-1]) ))
print(C)
zip() - creates pairs of all elements of iterables, you feed it A and B reversed (via slicing). Then you sum up each pair and create a list from those sums.
map( function, iterable) - applies the function to each element of the iterable
zip() works when both list have the same length, else you would need to leverage itertools.zip_longest() with a defaultvalue of 0.
K = [1,2,3,4,5,6]
P = list(map(sum, zip_longest(K,C,fillvalue=0)))
print(P)
Output:
[5, 7, 9] # zip of 2 same length lists A and B reversed
[6, 9, 12, 4, 5, 6] # ziplongest for no matter what length lists
You only need one loop if you want to search in same list back and forth or different list with same length (i and len(lst)-1-i).
Try not use build-ins such as sum, list, tuple, str, int as variable names, it will give you some nasty result in some case.
class Solution(object):
def plusOne(self, digits):
sum_val = 0
for i in range(len(digits)):
sum_val += digits[i]*pow(10, len(digits)-1-i)
return sum_val+1
sol = Solution()
dig = [1, 2, 3]
print(sol.plusOne(dig))
Output:
124
for A = [1, 2, 3] and B = [6, 5, 4].
You can use a list comprehension:
res = [A[i]+B[len(A)-i-1] for i in range(len(A))]
Or the zip() function and a list comprehension:
res = [a+b for (a, b) in zip(A, reversed(B))]
Result:
[5, 7, 9]
I have a bug in my attempt to add to a list a sequence of numbers recursively. E.g. if the input is [5,3,9], I do [5+1,3+2,9+3] and output [6,5,12]. I want to do this recursively so the way I'm doing it is going through and adding one to a smaller and smaller part of the list as below:
def add_position_recur(lst, number_from=0):
length = len(lst)
# base case
if (length <= 1):
lst = [x+1 for x in lst]
print "last is", lst
else:
lst = [x+1 for x in lst]
print "current list is", lst
add_position_recur(lst[1:], number_from)
return lst
The problem, though, is that all this does is add 1 to every element of the list. Where is the bug? Is it to do with the way I return the list in the base case?
When you recurse down your call stack you slice lst which creates a new list, this is not the same as what you return, so you will only ever return the changes you've applied to your list in the first call to the function, losing all changes further down the stack:
>>> add_position_recur([1,2,3])
[2, 3, 4]
This should have returned [2, 4, 6].
You need to consider reassembling the list on the way out to get the changes.
return [lst[0]] + add_position_recur(lst[1:], number_from)
and you need to return lst in your base case:
def add_position_recur(lst, number_from=0):
length = len(lst)
# base case
if (length <= 1):
lst = [x+1 for x in lst]
return lst
else:
lst = [x+1 for x in lst]
return [lst[0]] + add_position_recur(lst[1:], number_from)
>>> add_position_recur([1,2,3])
[2, 4, 6]
However, this is quite a complicated approach to this recursion. It is idiomatic for the base case to be the empty list, otherwise take the head and recurse down the tail. So something to consider which uses the number_from:
def add_position_recur(lst, number_from=1):
if not lst:
return lst
return [lst[0]+number_from] + add_position_recur(lst[1:], number_from+1)
>>> add_position_recur([1,2,3])
[2, 4, 6]
This also has the advantage(?) of not changing the passed in lst
Why don't you instead do something like this:
def func(lon, after=[]):
if not l:
pass
else:
v = len(lon) + lon[-1]
after.append(v)
func(lon[:-1], after)
return after[::-1]
The output of the function for the example you provided matches what you want.
Currently, you are simply adding 1 to each value of your list.
lst = [x+1 for x in lst]
Rather, you should be increasing a variable which is being added to x with each iteration of x in lst.
lst = [x+(lst.index(x)+1) for x in lst]
This solution assumes that you want the number being added to x to depend on its position in the list relative to the start of the list, rather than being dependent on the position of x relative to the first element which was >1. Meaning, do you want to add 1 or 3 to the value 2 in the following list? The solution above adds three.
lst = [0.5, 0.1, 2, 3]
I am looking for a way to easily split a python list in half.
So that if I have an array:
A = [0,1,2,3,4,5]
I would be able to get:
B = [0,1,2]
C = [3,4,5]
A = [1,2,3,4,5,6]
B = A[:len(A)//2]
C = A[len(A)//2:]
If you want a function:
def split_list(a_list):
half = len(a_list)//2
return a_list[:half], a_list[half:]
A = [1,2,3,4,5,6]
B, C = split_list(A)
A little more generic solution (you can specify the number of parts you want, not just split 'in half'):
def split_list(alist, wanted_parts=1):
length = len(alist)
return [ alist[i*length // wanted_parts: (i+1)*length // wanted_parts]
for i in range(wanted_parts) ]
A = [0,1,2,3,4,5,6,7,8,9]
print split_list(A, wanted_parts=1)
print split_list(A, wanted_parts=2)
print split_list(A, wanted_parts=8)
f = lambda A, n=3: [A[i:i+n] for i in range(0, len(A), n)]
f(A)
n - the predefined length of result arrays
def split(arr, size):
arrs = []
while len(arr) > size:
pice = arr[:size]
arrs.append(pice)
arr = arr[size:]
arrs.append(arr)
return arrs
Test:
x=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
print(split(x, 5))
result:
[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13]]
If you don't care about the order...
def split(list):
return list[::2], list[1::2]
list[::2] gets every second element in the list starting from the 0th element.
list[1::2] gets every second element in the list starting from the 1st element.
Using list slicing. The syntax is basically my_list[start_index:end_index]
>>> i = [0,1,2,3,4,5]
>>> i[:3] # same as i[0:3] - grabs from first to third index (0->2)
[0, 1, 2]
>>> i[3:] # same as i[3:len(i)] - grabs from fourth index to end
[3, 4, 5]
To get the first half of the list, you slice from the first index to len(i)//2 (where // is the integer division - so 3//2 will give the floored result of1, instead of the invalid list index of1.5`):
>>> i[:len(i)//2]
[0, 1, 2]
..and the swap the values around to get the second half:
>>> i[len(i)//2:]
[3, 4, 5]
B,C=A[:len(A)/2],A[len(A)/2:]
Here is a common solution, split arr into count part
def split(arr, count):
return [arr[i::count] for i in range(count)]
def splitter(A):
B = A[0:len(A)//2]
C = A[len(A)//2:]
return (B,C)
I tested, and the double slash is required to force int division in python 3. My original post was correct, although wysiwyg broke in Opera, for some reason.
If you have a big list, It's better to use itertools and write a function to yield each part as needed:
from itertools import islice
def make_chunks(data, SIZE):
it = iter(data)
# use `xragne` if you are in python 2.7:
for i in range(0, len(data), SIZE):
yield [k for k in islice(it, SIZE)]
You can use this like:
A = [0, 1, 2, 3, 4, 5, 6]
size = len(A) // 2
for sample in make_chunks(A, size):
print(sample)
The output is:
[0, 1, 2]
[3, 4, 5]
[6]
Thanks to #thefourtheye and #Bede Constantinides
This is similar to other solutions, but a little faster.
# Usage: split_half([1,2,3,4,5]) Result: ([1, 2], [3, 4, 5])
def split_half(a):
half = len(a) >> 1
return a[:half], a[half:]
There is an official Python receipe for the more generalized case of splitting an array into smaller arrays of size n.
from itertools import izip_longest
def grouper(n, iterable, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
This code snippet is from the python itertools doc page.
10 years later.. I thought - why not add another:
arr = 'Some random string' * 10; n = 4
print([arr[e:e+n] for e in range(0,len(arr),n)])
While the answers above are more or less correct, you may run into trouble if the size of your array isn't divisible by 2, as the result of a / 2, a being odd, is a float in python 3.0, and in earlier version if you specify from __future__ import division at the beginning of your script. You are in any case better off going for integer division, i.e. a // 2, in order to get "forward" compatibility of your code.
#for python 3
A = [0,1,2,3,4,5]
l = len(A)/2
B = A[:int(l)]
C = A[int(l):]
General solution split list into n parts with parameter verification:
def sp(l,n):
# split list l into n parts
if l:
p = len(l) if n < 1 else len(l) // n # no split
p = p if p > 0 else 1 # split down to elements
for i in range(0, len(l), p):
yield l[i:i+p]
else:
yield [] # empty list split returns empty list
Since there was no restriction put on which package we can use.. Numpy has a function called split with which you can easily split an array any way you like.
Example
import numpy as np
A = np.array(list('abcdefg'))
np.split(A, 2)
With hints from #ChristopheD
def line_split(N, K=1):
length = len(N)
return [N[i*length/K:(i+1)*length/K] for i in range(K)]
A = [0,1,2,3,4,5,6,7,8,9]
print line_split(A,1)
print line_split(A,2)
Another take on this problem in 2020 ... Here's a generalization of the problem. I interpret the 'divide a list in half' to be .. (i.e. two lists only and there shall be no spillover to a third array in case of an odd one out etc). For instance, if the array length is 19 and a division by two using // operator gives 9, and we will end up having two arrays of length 9 and one array (third) of length 1 (so in total three arrays). If we'd want a general solution to give two arrays all the time, I will assume that we are happy with resulting duo arrays that are not equal in length (one will be longer than the other). And that its assumed to be ok to have the order mixed (alternating in this case).
"""
arrayinput --> is an array of length N that you wish to split 2 times
"""
ctr = 1 # lets initialize a counter
holder_1 = []
holder_2 = []
for i in range(len(arrayinput)):
if ctr == 1 :
holder_1.append(arrayinput[i])
elif ctr == 2:
holder_2.append(arrayinput[i])
ctr += 1
if ctr > 2 : # if it exceeds 2 then we reset
ctr = 1
This concept works for any amount of list partition as you'd like (you'd have to tweak the code depending on how many list parts you want). And is rather straightforward to interpret. To speed things up , you can even write this loop in cython / C / C++ to speed things up. Then again, I've tried this code on relatively small lists ~ 10,000 rows and it finishes in a fraction of second.
Just my two cents.
Thanks!
from itertools import islice
Input = [2, 5, 3, 4, 8, 9, 1]
small_list_length = [1, 2, 3, 1]
Input1 = iter(Input)
Result = [list(islice(Input1, elem)) for elem in small_list_length]
print("Input list :", Input)
print("Split length list: ", small_list_length)
print("List after splitting", Result)
You can try something like this with numpy
import numpy as np
np.array_split([1,2,3,4,6,7,8], 2)
result:
[array([1, 2, 3, 4]), array([6, 7, 8])]