Python: Combine triple into a single string [duplicate] - python

This question already has answers here:
How to concatenate (join) items in a list to a single string
(11 answers)
Apply function to each element of a list
(4 answers)
Closed 6 months ago.
How to join every sublist to a single string in Python?
Here is the list :
L=[['1', '1', '0', '0', '0'],['1', '1', '1', '1', '0'],['0', '0', '1', '1', '0']]
My desired list would be :
D=['11000','11110','00110']

L = [['1', '1', '0', '0', '0'],['1', '1', '1', '1', '0'],['0', '0', '1', '1', '0']]
D = [''.join(sub_list) for sub_list in L]

You can either use a list comprehension:
L = [
['1', '1', '0', '0', '0'],
['1', '1', '1', '1', '0'],
['0', '0', '1', '1', '0']
]
D = [''.join(l) for l in L]
or the map function:
D = map(''.join, L) # returns a generator in python3, cast it to list to get one
Note that the most pythonic way of doing this is the list comprehension.

flat list can be made through reduce easily.
All you need to use initializer - third argument in the reduce function.
reduce(
lambda result, _list: result.append(''.join(_list)) or result,
L,
[])
or map and reduce in combination,
import operator
map(lambda l: reduce(operator.iconcat, l), L)
Above code works for both python2 and python3, but you need to import reduce module as from functools import reduce. Refer below link for details.
for python2
for python3

Related

How to pair 2 list into 1 list

I have a code like this:
def datauji(self):
uji = []
for x in self.fiturs:
a = [x[0],x[-5:]] #I think the problem in this line
uji.append(a)
return uji
with open('DataUjiBaru.csv','wb') as dub:
testing = csv.writer(dub)
datatest = d.datauji()
datatest.pop(0)
for x in datatest:
testing.writerow(x)
I want to pair the value in self.fiturs, In self.fiturs:
F37,0,1,0,1,1,1,0,1,0,2,1,0,0,0,1
F10,8,4,3,3,3,6,8,5,8,4,8,4,5,6,4
F8,1,0,2,0,0,0,2,0,0,0,0,0,2,0,0
So i want to pair index[0] and index[-5:] and write it to the csv, and the output on the csv like this:
F37,"['1', '0', '0', '0', '1']"
F10,"['8', '4', '5', '6', '4']"
F8,"['0', '0', '2', '0', '0']"
My Expectation in that csv is like this:
F37,1,0,0,0,1
F10,8,4,5,6,4
F8,0,0,2,0,0
How can I fix that?
You were correct about the issue with your code, it is found in the line:
a = [x[0],x[-5:]]
This creates nested items that look like this:
['F37', ['1', '0', '0', '0', '1']]
Here are two ways to fix this:
Option 1 - Use the splat* operator:
a = [x[0],*x[-5:]]
Option 2 - Concatenate two slices of your list:
a = x[:1] + x[-5:]
Both of these will remove the nesting of your lists, and instead give you lines looking like:
['F37', '1', '0', '0', '0', '1']
Which you can then write to your output file.

converting each element from string to int in nested list in python [duplicate]

This question already has answers here:
How do I convert all strings in a list of lists to integers?
(15 answers)
Closed 5 years ago.
I have data in python with nested lists, a part of which looks like:
data = [['214', '205', '0', '14', '710', '1813494849', '0'], ['214', '204', '0', '30', '710', '1813494856', '0'], ['214', '204', '0', '34', '710', '1813494863', '0'], ['213', '204', '0', '35', '710', '1813494870', '0'], ['213', '203', '0', '35', '710', '1813494877', '0']]
While converting the data using couple methods:
1.
new_data_list = [[int(x) for x in list] for list in data]
list=[]
for i in range(0,len(data)):
list.append([])
for j in range(0,len(data[i])):
b=int(data[i][j])
list[i].append(b)
I am getting the error which says:
> ValueError: invalid literal for int() with base 10: ''
There are no non-numeric data in my list of data. But there might be something with the header, like an empty header treated as non-numeric value as I have created a list of data from csv.
I wanted to know an efficient way which can convert each element of the list to int while keeping the data multi list.
Call int for each item in each nested list:
new_list = [[int(x) for x in lst] for lst in nested]
Or using map:
new_list = [list(map(int, lst)) for lst in nested]
A concise one is:
x = ['123', '12', '5']
r = list(map(int, x))
print(r)
>[123, 12, 5]

Convert a String in List format into List - python 3 [duplicate]

This question already has answers here:
Convert string to list. Python [string.split() acting weird]
(2 answers)
Closed 5 years ago.
In python3, I'd like to turn a string, like this:
my_str = "['1', '2', '3', '4', '72']"
into a list, like this:
my_list = ['1', '2', '3', '4', '72']
Is there a simple way to do this?
Many thanks, y'all.
Use ast.literal_eval:
>>> import ast
>>> my_str = "['1', '2', '3', '4', '72']"
>>> ast.literal_eval(my_str)
['1', '2', '3', '4', '72']
This is a much more safer option than using eval() because it fails if the data isn't safe.
import re
my_str = "[1', '2', '3', '4', '72']"
re.compile(r'(\d+)').findall(my_str)
['1', '2', '3', '4', '72']
Note: Using re you can get the desired output even if you had not put that ' in the string.

Filtering out a generator

Whats the best way to filter out some subsets from a generator. For example I have a string "1023" and want to produce all possible combinations of each of the digits. All combinations would be:
['1', '0', '2', '3']
['1', '0', '23']
['1', '02', '3']
['1', '023']
['10', '2', '3']
['10', '23']
['102', '3']
['1023']
I am not interested in a subset that contains a leading 0 on any of the items, so the valid ones are:
['1', '0', '2', '3']
['1', '0', '23']
['10', '2', '3']
['10', '23']
['102', '3']
['1023']
I have two questions.
1) If using a generator, whats the best way to filter out the ones with leading zeroes. Currently, I generate all combinations then loop through it afterwards and only continuing if the subset is valid. For simplicity I am only printing the subset in the sample code. Assuming the generator that was created is very long or if it constains a lot of invalid subsets, its almost a waste to loop through the entire generator. Is there a way to stop the generator when it sees an invalid item (one with leading zero) then filter it off 'allCombinations'
2) If the above doesn't exist, whats a better way to generate these combinations (disregarding combinations with leading zeroes).
Code using a generator:
import itertools
def isValid(subset): ## DIGITS WITH LEADING 0 IS NOT VALID
valid = True
for num in subset:
if num[0] == '0' and len(num) > 1:
valid = False
break
return valid
def get_combinations(source, comb):
res = ""
for x, action in zip(source, comb + (0,)):
res += x
if action == 0:
yield res
res = ""
digits = "1023"
allCombinations = [list(get_combinations(digits, c)) for c in itertools.product((0, 1), repeat=len(digits) - 1)]
for subset in allCombinations: ## LOOPS THROUGH THE ENTIRE GENERATOR
if isValid(subset):
print(subset)
Filtering for an easy and obvious condition like "no leading zeros", it can be more efficiently done at the combination building level.
def generate_pieces(input_string, predicate):
if input_string:
if predicate(input_string):
yield [input_string]
for item_size in range(1, len(input_string)+1):
item = input_string[:item_size]
if not predicate(item):
continue
rest = input_string[item_size:]
for rest_piece in generate_pieces(rest, predicate):
yield [item] + rest_piece
Generating every combination of cuts, so long it's not even funny:
>>> list(generate_pieces('10002', lambda x: True))
[['10002'], ['1', '0002'], ['1', '0', '002'], ['1', '0', '0', '02'], ['1', '0', '0', '0', '2'], ['1', '0', '00', '2'], ['1', '00', '02'], ['1', '00', '0', '2'], ['1', '000', '2'], ['10', '002'], ['10', '0', '02'], ['10', '0', '0', '2'], ['10', '00', '2'], ['100', '02'], ['100', '0', '2'], ['1000', '2']]
Only those where no fragment has leading zeros:
>>> list(generate_pieces('10002', lambda x: not x.startswith('0')))
[['10002'], ['1000', '2']]
Substrings that start with a zero were never considered for the recursive step.
One common solution is to try filtering just before using yield. I have given you an example of filtering just before yield:
import itertools
def my_gen(my_string):
# Create combinations
for length in range(len(my_string)):
for my_tuple in itertools.combinations(my_string, length+1):
# This is the string you would like to output
output_string = "".join(my_tuple)
# filter here:
if output_string[0] != '0':
yield output_string
my_string = '1023'
print(list(my_gen(my_string)))
EDIT: Added in a generator comprehension alternative
import itertools
my_string = '1023'
my_gen = ("".join(my_tuple)[0] for length in range(len(my_string))
for my_tuple in itertools.combinations(my_string, length+1)
if "".join(my_tuple)[0] != '0')

If all 9 strings in list is replaced: do something

As the title:
If all 9 strings in list is replaced, then a task should run.
Here is the code:
list = [
['0', '0', '0'],
['0', '0', '0'],
['0', '0', '0']
]
If all of them is either replaced by a "1" or "2" doesnt matter which is replaced by what. Then it should run a task.
So how do I if all of the 9 spots have been replaced by either a "1" or "2"?
There is simply too many possibilities to write all the combinations down, and compare them to the list.
How about this,
s = set(item for sublist in lists for item in sublist) # flat a list of lists into a set
if '0' not in s:
do_something()
You may achieve it using set() and itertools.chain() function as:
from itertools import chain
set(chain(*my_list)).issubset('12')
# ^ ^ ^ all items in set are either '1' or '2'
# ^ ^ creates a single list comprising the sub-list
# ^ uniques values in the chained list
where my_list is your nested list.
Note: Do not use list as variable type because list is the built-in keyword denoting the list data-type in Python.
Sample run:
# Sample function
>>> def check_list(my_list):
... return set(chain(*my_list)).issubset('12')
...
# Test Run:
>>> check_list([['0', '0'], ['0', '0']])
False
>>> check_list([['0', '1'], ['0', '0']])
False
>>> check_list([['1', '1'], ['1', '1']])
True
>>> check_list([['1', '2'], ['1', '2']])
True
Never name a variable a reserved word, i.e. list. But here is an easy way.
l = [
['0', '0', '0'],
['0', '0', '0'],
['0', '0', '0']
]
if all(all(int(x) for x in row) for row in l):
#do something
To check if they have been replaced by '1' or '2' and nothing else
all(all(i in ('1', '2') for i in sublist) for sublist in list)
I read your question is how to I check to see if all sublists contain only '1' and '2'?
>>> mylist = [list('121'),list('111'), list('222')]
>>> mylist
[['1', '2', '1'], ['1', '1', '1'], ['2', '2', '2']]
>>> all(item in ('1', '2') for sublist in mylist for item in sublist)
True
>>> mylist[0][0] = '0'
>>> mylist
[['0', '2', '1'], ['1', '1', '1'], ['2', '2', '2']]
>>> all(item in ('1', '2') for sublist in mylist for item in sublist)
False

Categories

Resources