Unpack an array filled with lists - python

I started with something like this:
[a,b,s,d]
[k,e,f,s,d]
[o,w,g]
Then I wanted to rearrange them by length in descending order so that I get this:
[k,e,f,s,d]
[a,b,s,d]
[o,w,g]
However, to do that, I appended each of those into an array as such:
arr = [[a,b,s,d], [k,e,f,s,d], [o,w,g]]
so that I could just use:
sorted(arr, key=len).reverse()
But now I can't unpack arr to just get:
[k,e,f,s,d]
[a,b,s,d]
[o,w,g]
Ideas?
Thanks.

reverse() is an in-place function:
arr = [['a','b','s','d'], ['k','e','f','s','d'], ['o','w','g']]
a = sorted(arr, key=len)
print a
# [['o', 'w', 'g'], ['a', 'b', 's', 'd'], ['k', 'e', 'f', 's', 'd']]
print a.reverse()
# None
print a
# [['k', 'e', 'f', 's', 'd'], ['a', 'b', 's', 'd'], ['o', 'w', 'g']]
reverse() has no output, but it does reverse the array.

Related

flip and swap alternate column in 2d array

This is my 2d list
array = ([a,b, c,d, e,f ,g,h], [s,t, u,v, w,x ,y,z])
I would like the output to be
array = ([g,h, e,f, c,d, a,b] ,[y,z, w,x, u,v, s,t])
I was using below to flip the array, but i am stuck to do alternate swap. can anyone help me. Thanks.
array = np.flip(array,axis=1)
You can play with reshape:
array = np.array([['a','b','c','d','e','f','g','h'],
['s','t','u','v','w','x','y','z']])
x,y = array.shape
np.flip(array.reshape((x, -1, 2)), axis=1).reshape(x,y)
output:
array([['g', 'h', 'e', 'f', 'c', 'd', 'a', 'b'],
['y', 'z', 'w', 'x', 'u', 'v', 's', 't']], dtype='<U1')

How to group similar sequence preserving order in Python? [duplicate]

This question already has an answer here:
How can I group equivalent items together in a Python list?
(1 answer)
Closed 3 years ago.
I want to split a list sequence of items in Python or group them if they are similar.
I already found a solution but I would like to know if there is a better and more efficient way to do it (always up to learn more).
Here is the main goal
input = ['a','a', 'i', 'e', 'e', 'e', 'i', 'i', 'a', 'a']
desired_ouput = [['a','a'], ['i'], ['e','e', 'e'], ['i', 'i'], ['a', 'a']
So basically I choose to group by similar neighbour.I try to find a way to split them if different but get no success dooing it.
I'm also keen on listening the good way to expose the problem
#!/usr/bin/env python3
def group_seq(listA):
listA = [[n] for n in listA]
for i,l in enumerate(listA):
_curr = l
_prev = None
_next= None
if i+1 < len(listA):
_next = listA[i+1]
if i > 0:
_prev = listA[i-1]
if _next is not None and _curr[-1] == _next[0]:
listA[i].extend(_next)
listA.pop(i+1)
if _prev is not None and _curr[0] == _prev[0]:
listA[i].extend(_prev)
listA.pop(i-1)
return listA
listA = ['a','a', 'i', 'e', 'e', 'e', 'i', 'i', 'a', 'a']
output = group_seq(listA)
print(listA)
['a', 'a', 'i', 'e', 'e', 'e', 'i', 'i', 'a', 'a']
print(output)
[['a', 'a'], ['i'], ['e', 'e', 'e'], ['i', 'i'], ['a', 'a']]
I think itertool.groupby is probably the nicest way to do this. It's flexible and efficient enough that it's rarely to your advantage to re-implement it yourself:
from itertools import groupby
inp = ['a','a', 'i', 'e', 'e', 'e', 'i', 'i', 'a', 'a']
output = [list(g) for k,g in groupby(inp)]
print(output)
prints
[['a', 'a'], ['i'], ['e', 'e', 'e'], ['i', 'i'], ['a', 'a']]
If you do implement it yourself, it can probably be much simpler. Just keep track of the previous value and the current list you're appending to:
def group_seq(listA):
prev = None
cur = None
ret = []
for l in listA:
if l == prev: # assumes list doesn't contain None
cur.append(l)
else:
cur = [l]
ret.append(cur)
prev = l
return ret

Unexpected result reversing Python array

When I write this code:
f=['a','b','c',['d','e','f']]
def j(f):
p=f[:]
for i in range(len(f)):
if type(p[i]) == list:
p[i].reverse()
p.reverse()
return p
print(j(f), f)
I expect that the result would be:
[['f', 'e', 'd'], 'c', 'b', 'a'] ['a', 'b', 'c', ['d', 'e', 'f']]
But the result I see is:
[['f', 'e', 'd'], 'c', 'b', 'a'] ['a', 'b', 'c', ['f', 'e', 'd']]
Why? And how can I write a code that do what I expect?
reverse modifies the list in place, you actually want to create a new list, so you don't reverse the one you've got, something like this:
def j(f):
p=f[:]
for i in range(len(f)):
if type(p[i]) == list:
p[i] = p[i][::-1]
p.reverse()
return p

Sorting a list using an alphabet string

I'm trying to sort a list containing only lower case letters by using the string :
alphabet = "abcdefghijklmnopqrstuvwxyz".
that is without using sort, and with O(n) complexity only.
I got here:
def sort_char_list(lst):
alphabet = "abcdefghijklmnopqrstuvwxyz"
new_list = []
length = len(lst)
for i in range(length):
new_list.insert(alphabet.index(lst[i]),lst[i])
print (new_list)
return new_list
for this input :
m = list("emabrgtjh")
I get this:
['e']
['e', 'm']
['a', 'e', 'm']
['a', 'b', 'e', 'm']
['a', 'b', 'e', 'm', 'r']
['a', 'b', 'e', 'm', 'r', 'g']
['a', 'b', 'e', 'm', 'r', 'g', 't']
['a', 'b', 'e', 'm', 'r', 'g', 't', 'j']
['a', 'b', 'e', 'm', 'r', 'g', 't', 'h', 'j']
['a', 'b', 'e', 'm', 'r', 'g', 't', 'h', 'j']
looks like something goes wrong along the way, and I can't seem to understand why.. if anyone can please enlighten me that would be great.
You are looking for a bucket sort. Here:
def sort_char_list(lst):
alphabet = "abcdefghijklmnopqrstuvwxyz"
# Here, create the 26 buckets
new_list = [''] * len(alphabet)
for letter in lst:
# This is the bucket index
# You could use `ord(letter) - ord('a')` in this specific case, but it is not mandatory
index = alphabet.index(letter)
new_list[index] += letter
# Assemble the buckets
return ''.join(new_list)
As for complexity, since alphabet is a pre-defined fixed-size string, searching a letter in it is requires at most 26 operations, which qualifies as O(1). The overall complexity is therefore O(n)

Multi-item sort based with two different list items and reorder/reshuffle?

I have a nested list that looks like this:
li = [['m', 'z', 'asdgwergerwhwre'],
['j', 'h', 'asdgasdgasdgasdgas'],
['u', 'a', 'asdgasdgasdgasd'],
['i', 'o', 'sdagasdgasdgdsag']]
I would like to sort this list alphabetically, BUT using either the first or second element in each sublist. For the above example, the desired output would be:
['a', 'u', 'asdgasdgasdgasd']
['h', 'j', 'asdgasdgasdgasdgas']
['i', 'o', 'sdagasdgasdgdsag']
['m', 'z', 'asdgwergerwhwre']
What is the best way to achieve this sort?
As the first step we perform some transformation (swap for first two items - if needed) and at the second aplly simple sort:
>>> sorted(map(lambda x: sorted(x[:2]) + [x[2]], li))
[['a', 'u', 'asdgasdgasdgasd'],
['h', 'j', 'asdgasdgasdgasdgas'],
['i', 'o', 'sdagasdgasdgdsag'],
['m', 'z', 'asdgwergerwhwre']]
You can make use of the built-in method sorted() to accomplish some of this. You would have to reverse the order of the list if you wanted to reverse the way it was printed, but that's not too difficult to do.
def rev(li):
for l in li:
l[0], l[1] = l[1], l[0]
return li
new_list = sorted(rev(li))
If you wanted to sort the list based on a specific index, you can use sorted(li, key=lambda li: li[index]).
import pprint
li = [['m', 'z', 'asdgwergerwhwre'],
['j', 'h', 'asdgasdgasdgasdgas'],
['u', 'a', 'asdgasdgasdgasd'],
['i', 'o', 'sdagasdgasdgdsag']]
for _list in li:
_list[:2]=sorted(_list[:2])
pprint.pprint(sorted(li))
>>>
[['a', 'u', 'asdgasdgasdgasd'],
['h', 'j', 'asdgasdgasdgasdgas'],
['i', 'o', 'sdagasdgasdgdsag'],
['m', 'z', 'asdgwergerwhwre']]

Categories

Resources