Related
Here is a list A=[1,1,1,2,2,2,4,5,6,6,7,7,7]
Can we have an algorithm that modifies all the numbers that occur more than twice to be maximized twice in list A?
e.g. list new_A=[1,1,2,2,4,5,6,6,7,7]
I have tried the conditions to separate:
if Counter(list A)[num]>2:```
You can use groupby and islice:
from itertools import groupby, islice
lst = [1,1,1,2,2,2,4,5,6,6,7,7,7]
output = [x for _, g in groupby(lst) for x in islice(g, 2)]
print(output) # [1, 1, 2, 2, 4, 5, 6, 6, 7, 7]
You can do something like this:
from collections import Counter
max_accurance =2
list_A=[1,1,1,2,2,2,4,5,6,6,7,7,7]
d = dict(Counter(list_A))
new_list=[]
for k,v in d.items():
if v>=max_accurance:
new_list.extend([k]*max_accurance)
else:
new_list.append(k)
output
[1, 1, 2, 2, 4, 5, 6, 7, 7]
Most compressed way I could think of:
import operator as op
A=[1,1,1,2,2,2,4,5,6,6,7,7,7]
B = []
for elem in set(A):
B.extend([elem, elem]) if op.countOf(A, elem) > 2 else B.extend([elem])
Output:
[1, 1, 2, 2, 4, 5, 6, 7, 7]
I am new to python and so I am experimenting a little bit, but I have a little problem now.
I have a list of n numbers and I want to make a new list that contains only every second pair of the numbers.
So basically if I have list like this
oldlist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
then I want that the new list looks like this
newlist = [3, 4, 7, 8]
I already tried the slice() function, but I didn't find any way to make it slice my list into pairs. Then I thought that I could use two slice() functions that goes by four and are moved by one, but if I merge these two new lists they won't be in the right order.
If you enumerate the list, you'd be taking those entries whose indices give either 2 or 3 as a remainder when divided by 4:
>>> [val for j, val in enumerate(old_list) if j % 4 in (2, 3)]
[3, 4, 7, 8]
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = [a[i] for i in range(len(a)) if i%4 in (2,3)]
# Output: b = [3, 4, 7, 8]
Here, we use the idea that the 3rd,4th,7th,8th..and so on. indices leave either 2 or 3 as the remainder when divided by 4.
first_part = oldList[2::4] # every 4th item, starting from the 3rd item
second_part = oldList[3::4] # every 4th item starting from the 4th item
pairs = zip(first_part, second_part)
final_result = chain.from_iterable(pairs)
Break this problem in to parts.
first = oldlist[2::4]
second = oldlist[3::4]
pairs = [(x, y) for x, y in zip(first, second)]
Now unwrap the pairs:
newlist = [x for p in pairs for x in p]
Combining:
newlist = [z for p in [(x, y) for x, y in zip(oldlist[2::4], oldlist[3::4])] for z in p]
I would firstly divide original list into two lists, with odd and even elements. Then iterate over zip of them.
old = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = list()
part1, part2 = old[::2], old[1::2]
for i, z in enumerate(zip(part1,part2)):
if i % 2 == 0:
result.extend(z)
You could use a double range:
oldlist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
newlist = []
for i,j in zip(range(2, len(oldlist), 4), range(3, len(oldlist), 4)):
newlist += [oldlist[i], oldlist[j]]
#> newlist: [3, 4, 7, 8]
import more_itertools
oldlist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[*more_itertools.interleave(oldlist[2::4], oldlist[3::4])]
# [3, 4, 7, 8]
oldlist[2::4], oldlist[3::4]: slice 4th item
[*more_itertools.interleave(...)]: interleave the two above and convert back to a list
Here is what I have come up with:
oldList = list(range(1,10))
newList = []
for i in oldList:
if (i%2 == 0) and (i%4 != 0):
try:
newList.append(i+1)
newList.append(i+2)
except IndexError:
break
Result:
>>> newList
[3, 4, 7, 8]
I want to duplicate an specific element as many times as indicated.
The original list would look like this:
list=[1,2,3,4,5,6,7,8,9]
And here would have to be the duplicator and the element of the list that we want to duplicate.
times=4
num=4
The final list would have to look like this:
list=[1,2,3,4,4,4,4,5,6,7,8,9]
There are many ways to do it and if your list only have one occurrence of the number this is likely the simplest way
lst = [1,2,3,4,5,6,7,8,9]
num = 4
times = 4
ix = lst.index(num)
lst[ix:ix+1] = [num] * times
You can simply use list repetition and concatenation:
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]
times = 4
num = 4
ind = lst.index(num)
result = lst[:ind] + [num] * times + lst[ind + 1:]
print(result)
[1, 2, 3, 4, 4, 4, 4, 5, 6, 7, 8, 9]
You can try with this:
ex_list = [1,2,3,4,5,6,7,8,9]
times=4
num=4
new_list = sorted(ex_list + [ex_list[ex_list.index(times)]] * (num-1))
print(new_list)
Output:
[1, 2, 3, 4, 4, 4, 4, 5, 6, 7, 8, 9]
I have a base list [1,4,10] which needs to be converted to a list having consecutive elements of each element in the base list in an efficient way
Examples:
If I need 2 consecutive numbers then [1,4,10] will be [1,2,4,5,10,11].
If 3 consecutive numbers then [1,4,10] will be [1,2,3,4,5,6,10,11,12].
arr=[1,4,10]
con=3
[r + i for r in arr for i in range(con)]
# [1, 2, 3, 4, 5, 6, 10, 11, 12]
Here's a one liner, assuming the list is x and the number of 'consecutives' is c:
reduce(lambda a, b: a + b, map(lambda x: range(x, x+c), x))
a = [1,4,10]
k = 3 #no of consecutive
x=[range(b,b+k) for b in a]
output = [m for d in x for m in d]
Here is one way. itertools.chain removes the need for explicit nested loops.
from itertools import chain
def consecutiver(lst, n=3):
return list(chain.from_iterable(range(i, i+n) for i in lst))
res = consecutiver([1, 4, 10], 2)
# [1, 2, 4, 5, 10, 11]
res2 = consecutiver([1, 4, 10], 3)
# [1, 2, 3, 4, 5, 6, 10, 11, 12]
I want to do following:
1] compare each element in list a with b and map similar values.
a=[1, 2, 3, 6, 4, 5, 7, 8, 9]
b=[4, 4, 5, 5, 7, 7, 9, 9, 10]
I tried following:
c = set(a) & set(b)
>>> set([9,4,5,7])
2] I want these mapped values in same numbering order as appear in list b, such as 4,5,7,9.
3] and lastly I want to use these key values (4,5,7,9) and generate corresponding values from list a, such as:
4 (1,2)
5 (3,6)
7 (4,5)
9 (7,8)
Any suggestions would be highly appreciative?
Now that you've updated your question, I see that what you really want is just a map of keys to values:
a = [1, 2, 3, 6, 4, 5, 7, 8, 9]
b = [4, 4, 5, 5, 7, 7, 9, 9, 10]
r = dict([(x, []) for x in b])
for k, v in zip(b, a):
r[k] += [v,]
Here's how to use the results:
>>> for k, v in r.items():
... print k, v
...
9 [7, 8]
10 [9,]
4 [1, 2]
5 [3, 6]
7 [4, 5]
>>>
>>> print r[4]
[1, 2]
Here's an optimized version that will work faster with less memory usage:
from itertools import izip
from collections import defaultdict
r = defaultdict(list)
for k, v in izip(b, a):
r[k] += [v]
To solve your problem 3, you will need to compare each list against the opposing set. And that will solve your #2 automatically.
There are other ways to solve #2, like using an OrderedSet (like the recipe linked to in the collections docs), but since they won't solve #3, there's no point getting into that.
If the a values are very large, you might want to build an index structure—a dict that maps values to collections of indices—to make this faster. Like this:
rev_a = collections.defaultdict(list)
for index, value in enumerate(a):
rev_a[value].append(index)
And then the lookup part becomes even easier, and faster:
for b_value in b:
a_indices = rev_a[b_value]
if a_indices:
a_str = ','.join(map(str, a_indices))
print('{} is associated with ({})'.format(b_value, a_str))
Or, if you want to create some kind of structure instead of printing out on the fly:
results = [(b_value, rev_a[b_value]) for b_value in b]
results = OrderedDict((b_value, rev_a[b_value]) for b_value in b)
# etc.
That doesn't actually produce the output you asked for, but… I'm not sure what the output you asked for is supposed to come from. Unless you're taking the matching indices from the other list, then looking them up in the first list? That's… odd to say the least. At any rate, an index structure like this should make it trivial to implement any rule you come up with, even a much odder one, as long as you can explain it.
For example, replace the a_str line with this:
a_str = ','.join(str(a[a_index] for index in a_indices))
… and you get your desired output.
You can use a list comprehension
>>> a=[1, 2, 3, 6, 4, 5, 7, 8, 9]
>>> b=[4, 4, 5, 5, 7, 7, 9, 9, 10]
>>> [x for x in a if x in b]
[4, 5, 7, 9]