list splicing variable assignments automation - python

Imagine that you have a list of strings.
lst = ['a','b17','c','dz','e','ff','e3','e66']
you want to seperate those strings into individual variables
a = lst[:7]
b = lst[7:14]
c = lst[14:21]
Im wondering if there is a pythonic way of handling this instead of spending time typing out every single list splice.

You can use a generator expression to produce the slices and unpack them to your desired variables:
a, b, c = (lst[i:i+7] for i in range(0, 21, 7))
But that would produce an error of too many items to unpack if there are more than 21 items in the list, so it's better to use a list comprehension to keep it a list instead of individual variables:
[lst[i:i+7] for i in range(0, len(lst), 7)]

Try this method:
def f(lst,n):
l=[]
range_=list(range(0,len(lst),n))
for x,y in zip(range_,range_[1:]):
l.append(lst[x:y])
return l
print(f(lst,7))
Output with lst as:
lst = ['a','b17','c','dz','e','ff','e3','e66']*5
Is:
[['a', 'b17', 'c', 'dz', 'e', 'ff', 'e3'], ['e66', 'a', 'b17', 'c', 'dz', 'e', 'ff'], ['e3', 'e66', 'a', 'b17', 'c', 'dz', 'e'], ['ff', 'e3', 'e66', 'a', 'b17', 'c', 'dz'], ['e', 'ff', 'e3', 'e66', 'a', 'b17', 'c']]

Related

Storing The Output of a Permutation as a List of Lists

When I run the following code I get rows of tuples:
{perm = itertools.permutations(['A','B','C','D','E','F'],4)
for val in perm:
print(val)}.
How do I make the code give me the output as a single list of lists instead of rows of tuples?
When I run the code I get something like this
('F', 'E', 'B', 'C')
('F', 'E', 'B', 'D')
('F', 'E', 'C', 'A')
('F', 'E', 'C', 'B')
type here
etc.
What I want is something like this
[['F', 'E', 'B', 'C'],
['F', 'E', 'B', 'D'],
['F', 'E', 'C', 'A'],...,]
cast val into a list and append it to another list.
import itertools
perm = itertools.permutations(['A','B','C','D','E','F'],4)
result = []
for val in perm:
result.append(list(val))
print(result)
The question is, do you want to generate all permutations and store them?
As you have it now, the generator will give you one permutation each time, which is memory efficient.
You can generate all of them into a list of lists, but just think if you really want that, since the number of permutations could be very large.

How to convert numerical strings inside a mixed list of list to int (Python)

how do I convert all the numerical strings, inside a list of list that contains both alphabetical, and numerical strings, into an integer?
My Output:
[['69', ' Test', 'Results'], ['A', 'B', 'C'], ['D', '420', 'F']]
Intended Output:
[[69, ' Test', 'Results'], ['A', 'B', 'C'], ['D', 420, 'F']]
Note that my code reads a CSV file. Thanks everyone
def get_csv_as_table(a, b):
s = False
import csv
with open(a) as csv_file:
file_reader = csv.reader(csv_file, delimiter=b)
member = list(file_reader)
print(member)
print ("Enter filename: ")
a = input()
print ("Enter the delimiter: ")
b = input()
get_csv_as_table(a, b)
You can use list comprehension to achieve this. The only minor downside to this is that you will be creating a new list for this instead of modifying the existing list.
my_list = [['69', 'Test', 'Results'], ['A', 'B', 'C'], ['D', '420', 'F']]
filtered_list = [
[int(item) if item.isdigit() else item for item in sub_list]
for sub_list in my_list
]
If you want to edit the list in-place, you can use traditional for-loop. The following code will edit the existing list without creating a new list. This could turn out to be useful in case you have a large list.
my_list = [['69', 'Test', 'Results'], ['A', 'B', 'C'], ['D', '420', 'F']]
for i in range(len(my_list)):
for j in range(len(my_list[i])):
if my_list[i][j].isdigit():
my_list[i][j] = int(my_list[i][j])
str.isdigit() checks if a given string is a number or not. An important note to keep in mind is that, it does not work for floating-point numbers, just integers. Once the condition passes, the item is converted to integer.
Yoy have to combine 2 levels of list-comprehension and use str.isdigit()
values = [
[int(val) if val.isdigit() else val for val in row]
for row in values
]
Try with 2-level list comprehension and int()+.isdigit() power combo in list comprehension ;-)
l=[['69', ' Test', 'Results'], ['A', 'B', 'C'], ['D', '420', 'F']]
l=[[int(y) if y.isdigit() else y for y in x] for x in l]
print(l)
Output:
[[69, ' Test', 'Results'], ['A', 'B', 'C'], ['D', 420, 'F']]
.isdigit() only works on string representation of pure integers, In case if you have floats too then replace '.' to nothing ;-)
l=[['69', ' Test', 'Results'], ['A', 'B', 'C'], ['D', '420', 'F']]
l=[[float(y) if y.replace('.','').isdigit() else y for y in x] for x in l]
print(l)
Output:
[[69.0, ' Test', 'Results'], ['A', 'B', 'C'], ['D', 420.0, 'F']]

Moving a bunch of distinct items to the end of a python list

I have this python list:
['Intercept', 'a', 'country[T.BE]', 'country[T.CY]', 'country[T.DE]', 'b', 'c', 'd', 'e']
I want the country items at the end:
['Intercept', 'a', 'b', 'c', 'd', 'e', 'country[T.BE]', 'country[T.CY]', 'country[T.DE]']
How to accomplish this?
(Note, the items are column headers of a dataframe that I will use for regression analysis. The column names and the weird ordering are generated by patsy.dmatrices.)
I tried sorting, pop, del, and list comprehension, but to no avail. In this case I decided not to explain what I did to solve this problem and did not work. It is a simple problem, and unlike one commentators, I do not have decades of programming experience.
If your logic is to put any item that contains country to the back, use sorted with key:
l = ['Intercept', 'a', 'country[T.BE]', 'country[T.CY]', 'country[T.DE]', 'b', 'c', 'd', 'e']
sorted(l, key=lambda x: 'country' in x)
Output:
['Intercept',
'a',
'b',
'c',
'd',
'e',
'country[T.BE]',
'country[T.CY]',
'country[T.DE]']
Here I assume having or not the country[ text is what you want to split... then you can use:
li = ['Intercept', 'a', 'country[T.BE]', 'country[T.CY]', 'country[T.DE]', 'b', 'c', 'd', 'e']
[x for x in li if not 'country[' in x] + [x for x in li if 'country[' in x]

Unique combinations from list with "distance limit"

Given the list a = ['a', 'b', 'c', 'd', 'e'], I would use itertools.combinations to get all unique combos like ['ab', 'ac', ...], as per the classic SO answer
How can I limit the unique combinations to items that are not farther away than n spots?
Example
If I want list items no more than n=2 spots away, I would accept 'ab' and 'ac' as combinations but not 'ae', because the distance between 'a' and 'e' is greater than n=2
Edit - code
Below the plain python code solution, which I'd avoid due to the double-for loop, that is not ideal for large lists
a = ['a', 'b', 'c', 'd', 'e']
n_items = len(a)
n_max_look_forward = 2
unique_combos = []
for i, item in enumerate(a):
for j in range(i+1, min(i+n_max_look_forward+1, n_items)):
unique_combos.append( item+a[j] )
print(unique_combos)
Complexity-wise, your solution is close to the best possible.
You could refactor it to be a generator to generate the values only when you need them so that you don't have to hold all of them in memory at the same time:
def combis(source, max_distance=2):
for i, item in enumerate(source):
for j in range(i+1, min(i+max_distance+1, len(source))):
yield item+source[j]
You can then iterate over the generator:
>>> for combi in combis(['a', 'b', 'c', 'd', 'e']):
... print(combi)
...
ab
ac
bc
bd
cd
ce
de
If you need all of them in memory as a list, you can still use the generator to initialise it:
>>> list(combis(['a', 'b', 'c', 'd', 'e']))
['ab', 'ac', 'bc', 'bd', 'cd', 'ce', 'de']

Python merging sublist

I've got the following list :
[['a','b','c'],['d','e'],['f','g','h','i',j]]
I would like a list like this :
['abc','de','fghij']
How is it possible?
[Edit] : in fact, my list could have strings and numbers,
l = [[1,2,3],[4,5,6], [7], [8,'a']]
and would be :
l = [123,456, 7, 8a]
thx to all,
you can apply ''.join method for all sublists.
This can be done either using map function or using list comprehensions
map function runs function passed as first argument to all elements of iterable object
initial = ['a', 'b', 'c'], ['d', 'e'], ['f', 'g', 'h', 'i', 'j']]
result = map(''.join, initial)
also one can use list comprehension
initial = ['a', 'b', 'c'], ['d', 'e'], ['f', 'g', 'h', 'i', 'j']]
result = [''.join(sublist) for sublist in initial]
Try
>>> L = [['a','b','c'],['d','e'],['f','g','h','i','j']]
>>> [''.join(x) for x in L]
['abc', 'de', 'fghij']

Categories

Resources