List comprehension function for odd-even numbers - python

I am trying to print a list containing 2 lists at index 0 and 1. One list contains even numbers and the other one odd numbers.
Also, I want to do it with list comprehension and use only one list variable.
even_odd = [[],[]]
even_odd = [even_odd[0].append(a) if a%2 == 0 else even_odd[1].append(a) for a in range(20)]
Expected Output:
[[0, 2, 4, 6, 8, 10, 12, 14, 16, 18], [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]]
Using list comprehension

You can do it with two range by iterating in 2 interval
even_odd = [list(range(0, 19, 2)), list(range(1, 20, 2))]
# [[0, 2, 4, 6, 8, 10, 12, 14, 16, 18], [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]]

Related

How to define index based on sequence with starting and ending values

I've got a set of indices that defines the starts:
Int64Index([0, 3, 5, 6, 7, 8, 10, 15, 20, 22], dtype='int64')
and ends:
Int64Index([2, 5, 7, 8, 9, 10, 12, 17, 22, 24], dtype='int64')
of the ranges that should be used as desirable index. In other words, I'd like to obtain an index that would include all integers from 0 to 2 (inclusive), then from 3 to 5 (inclusive), ..., from 10 to 12 (inclusive), from 15 to 17 (inclusive) and so on. The resulting index would be:
Int64Index([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, **15**, 16, 17, **20**, 21, 22, 23, 24], dtype='int64')
(please note the break before 15 and 20). So the pairs of subsequent values would define the ranges and then those ranges would be joined together.
How can I obtain that?
My attempt is:
np.unique(np.concatenate([np.arange(start, end + 1) for start, end in zip(indices_starts, indices_ends)]))
But it feels like there must be more straighforward and potentially faster solution.
start = [0, 3, 5, 6, 7, 8, 10, 15, 20, 22]
end = [2, 5, 7, 8, 9, 10, 12, 17, 22, 24]
# Create an empty list for your indexes
new_idx = []
# Add the new indexes
for s, e in zip(start, end):
new_idx.extend(list(range(s,e+1)))
# Drop duplicated values
list(set(new_idx))
Hope it helps!
Your result index list is not accurate according to your description. With the condition of the index ranges being INCLUSIVE, the resulting index list would be:
starts = [0, 3, 5, 6, 7, 8, 10, 15, 20, 22]
ends = [2, 5, 7, 8, 9, 10, 12, 17, 22, 24]
indexes = []
for i in range(len(starts)):
indexes.extend(list(range(starts[i], ends[i] + 1)))
print(indexes)
# [0, 1, 2, 3, 4, 5, 5, 6, 7, 6, 7, 8, 7, 8, ... 20, 21, 22, 22, 23, 24]
With the condition of the index ranges being EXCLUSIVE:
...
for i in range(len(starts)):
indexes.extend(list(range(starts[i], ends[i])))
print(indexes)
# [0, 1, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 10, 11, 15, 16, 20, 21, 22, 23]

How to remove numbers in a NumPy array?

I want to know how I can remove the numbers resulted by the code from the original list, based on How to find larger numbers of any selected number in a series in an ascending order in NumPy?
EXAMPLE:
Series of random numbers:
4, 8, 5, 9, 3, 11, 17, 19, 9, 15, 16
X=4, Then:
4, 8, 9, 11, 17, 19 (We call this ROUND 1)
The numbers resulted in ROUND 1 are removed and the operation goes for the new list as follows:
5, 3, 9, 15, 16
So if we apply the code to the new list, it will generate new results:
X=5, Then:
5, 9, 15, 16
Edit:
a = np.array([4, 8, 5, 9, 3, 11, 17, 19, 9, 15, 16])
X = 4
withreps = np.maximum.accumulate(a[np.argmax(a==X):])
result = withreps[np.where(np.diff(withreps, prepend=withreps[0]-1))]
result
# array([ 4, 8, 9, 11, 17, 19])
Check out the following code
import numpy as np
rand_nums = np.array([4, 8, 5, 9, 3, 11, 17, 19, 9, 15, 16])
round_one = np.array([4, 8, 9, 11, 17, 19])
res = np.setdiff1d(rand_nums, round_one)
print(res)
# output
>>> array([ 3, 5, 15, 16])

Split list at a specific value

I am trying to write a code that splits lists in a class of lists in two when a certain value is a middle element of the list and then produce two lists where the middle element becomes the end element in the first list and the first element in the second one.
There can be more than n middle elements in the list so the result must be n+1 lists.
Example:
A = [[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],[16,17,18,19,20,21,22,23,24,25],[26,27,28,29]]
P = [4,7,13,20]
n = len(Points) # in this case n = 4
I am looking for a result that looks like this:
A = [[0,1,2,3,4],[4,5,6,7],[7,8,9,10,11,12,13],[13,14,15],[16,17,18,19,20],[20,21,22,23,24,25],[26,27,28,29]]
Since n = 4 and it will produce 5 lists, note that the answer has 6 lists because the last list doesn't have any value of P in and therefore stays intact.
I haven't been able to produce anything as I am new to python and it is hard to formulate this problem.
Any help is appreciated!
You can first recover all indices of the provided values and then slice accordingly.
Code
def split_at_values(lst, values):
indices = [i for i, x in enumerate(lst) if x in values]
for start, end in zip([0, *indices], [*indices, len(lst)]):
yield lst[start:end+1]
# Note: remove +1 for separator to only appear in right side slice
Example
values = {4, 7, 13, 20}
lst = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
print(*split_at_values(lst, values))
Output
[0, 1, 2, 3, 4] [4, 5, 6, 7] [7, 8, 9, 10, 11, 12, 13] [13, 14, 15]
You can then apply this iteratively to you input list A to get the desired result. Alternatively you can use itertools.chain.from_iterable.
from itertools import chain
values = {4, 7, 13, 20}
lst_A = [[0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
[16, 17, 18, 19, 20, 21, 22, 23, 24, 25],
[26, 27, 28, 29]]
output = list(chain.from_iterable(split_at_values(sublst, values) for sublst in lst_A))
print(output)
Output
[[0, 1, 2, 3, 4],
[4, 5, 6, 7],
[7, 8, 9, 10, 11, 12, 13],
[13, 14, 15],
[16, 17, 18, 19, 20],
[20, 21, 22, 23, 24, 25],
[26, 27, 28, 29]]
You can keep appending the sub-list items to the last sub-list of the output list, and if the current item is equal to the next item in Points, append a new sub-list to the output with the same item and pop the item from Points:
output = []
for l in List:
output.append([])
for i in l:
output[-1].append(i)
if Points and i == Points[0]:
output.append([i])
Points.pop(0)
With your sample input, output would become:
[[0, 1, 2, 3, 4], [4, 5, 6, 7], [7, 8, 9, 10, 11, 12, 13], [13, 14, 15], [16, 17, 18, 19, 20], [20, 21, 22, 23, 24, 25], [26, 27, 28, 29]]

Python breaking a single list into multiple sublists [duplicate]

This question already has answers here:
How do I split a list into equally-sized chunks?
(66 answers)
Closed 4 years ago.
In python I want to take a list and break it into a list of lists.
If I have a list that is 20 numbers long, I want to turn it into a list of two lists, each 5 numbers long.
Input
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
Output
new_nums = [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19]]
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
result = [nums[x:x+5] for x in range(0, len(nums), 5)]
print(result)
#Output:
[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19]]

Efficient way to find index of elements in a large list of integers starting with max to min elements

I have a large list of integers unsorted, numbers might be duplicated. I would like to create another list which is a list of sub-lists of indexes from the first list starting with max element to min, in decreasing order.
For example, if I have a list like this:
list = [4, 1, 4, 8, 5, 13, 2, 4, 3, 7, 14, 4, 4, 9, 12, 1, 6, 14, 10, 8, 6, 4, 11, 1, 2, 11, 3, 9]
The output should be:
indexList = [[10, 17], [5], [14], [22, 25], [18], [13, 27], [3, 19], [9], [16, 20], [4], [0, 2, 7, 11, 12, 21], [8, 26], [6, 24], [1, 15, 23]]
where, [10, 17] is the index of where '14' is present and so on...
Shared my code below. Profiling it using cProfile for a list of around 9000 elements takes around ~6 seconds.
def indexList(list):
# List with sorted elements
sortedList = sorted(list, reverse = True)
seen = set()
uSortedList = [x for x in sortedList if x not in seen and not seen.add(x)]
indexList = []
for e in uSortedList:
indexList.append([i for i, j in enumerate(list) if j == e])
return indexList
Here you go:
def get_list_indices(ls):
indices = {}
for n, i in enumerate(ls):
try:
indices[i].append(n)
except KeyError:
indices[i] = [n]
return [i[1] for i in sorted(indices.items(), reverse=True)]
test_list = [4, 1, 4, 8, 5, 13, 2, 4, 3, 7, 14, 4, 4, 9, 12, 1, 6, 14, 10, 8, 6, 4, 11, 1, 2, 11, 3, 9]
print(get_list_indices(test_list))
Based on some very basic testing, it is about twice as fast as the code you posted.

Categories