convert a list into a list of tuples with None included
Question:
I want to convert a list like this:
L = [‘ad’, ‘bc’, ‘gh’, ‘kj’, ‘ws’, ‘er’, ‘th’]
into [(‘ad’, ‘bc’, ‘gh’, ‘kj’, ‘ws’), (‘er’, ‘th’, None, None, None)] using python 3
The tuples will contain the equal amount of elements even if the list doesn’t provide enough elements. So if i have 6 elements, i will get two tuples, one full of 5 elements and the other will have only one element and 4 Nones. But if i have only 5 elements i should get a list of one tuple containing 5 elements.
i tried zip but it doesn’t give me the desired result
Answers:
You can use grouper
from the more_itertools
package for this:
from more_itertools import grouper
l = ['ad', 'bc', 'gh', 'kj', 'ws', 'er', 'th']
result = list(grouper(l, 5, incomplete="fill", fillvalue=None))
print(result)
gives
[('ad', 'bc', 'gh', 'kj', 'ws'), ('er', 'th', None, None, None)]
Alternatively, as Tomerikoo points out, you can construct the grouper
function using itertools
in the standard library:
from itertools import zip_longest
def grouper(iterable, n, *, incomplete='fill', fillvalue=None):
"Collect data into non-overlapping fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, fillvalue='x') --> ABC DEF Gxx
# grouper('ABCDEFG', 3, incomplete='strict') --> ABC DEF ValueError
# grouper('ABCDEFG', 3, incomplete='ignore') --> ABC DEF
args = [iter(iterable)] * n
if incomplete == 'fill':
return zip_longest(*args, fillvalue=fillvalue)
if incomplete == 'strict':
return zip(*args, strict=True)
if incomplete == 'ignore':
return zip(*args)
else:
raise ValueError('Expected fill, strict, or ignore')
Python code:
def getTuples(size):
intSize = size // 5
if size / 5 > intSize:
return (intSize + 1) * 5
else:
return intSize * 5
def convert(l):
new = []
t = ()
tValue = 0
for i in range(0, getTuples(len(l))):
tValue += 1
try:
val = l[i]
except IndexError:
val = None
if tValue == 5:
new.append(t)
t = ()
else:
t = t + (val,)
new.append(t)
L = ['ad', 'bc', 'gh', 'kj', 'ws', 'er', 'th']
L3 = list()
idx = 0
while idx < len(L):
L2 = list()
for idx2 in range(5):
L2.append(L[idx])
idx = idx +1
if idx >= len(L):
break
while idx2 < 4:
L2.append(None)
idx2 = idx2 + 1
L3.append(tuple(L2))
print(L3)
I want to convert a list like this:
L = [‘ad’, ‘bc’, ‘gh’, ‘kj’, ‘ws’, ‘er’, ‘th’]
into [(‘ad’, ‘bc’, ‘gh’, ‘kj’, ‘ws’), (‘er’, ‘th’, None, None, None)] using python 3
The tuples will contain the equal amount of elements even if the list doesn’t provide enough elements. So if i have 6 elements, i will get two tuples, one full of 5 elements and the other will have only one element and 4 Nones. But if i have only 5 elements i should get a list of one tuple containing 5 elements.
i tried zip but it doesn’t give me the desired result
You can use grouper
from the more_itertools
package for this:
from more_itertools import grouper
l = ['ad', 'bc', 'gh', 'kj', 'ws', 'er', 'th']
result = list(grouper(l, 5, incomplete="fill", fillvalue=None))
print(result)
gives
[('ad', 'bc', 'gh', 'kj', 'ws'), ('er', 'th', None, None, None)]
Alternatively, as Tomerikoo points out, you can construct the grouper
function using itertools
in the standard library:
from itertools import zip_longest
def grouper(iterable, n, *, incomplete='fill', fillvalue=None):
"Collect data into non-overlapping fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, fillvalue='x') --> ABC DEF Gxx
# grouper('ABCDEFG', 3, incomplete='strict') --> ABC DEF ValueError
# grouper('ABCDEFG', 3, incomplete='ignore') --> ABC DEF
args = [iter(iterable)] * n
if incomplete == 'fill':
return zip_longest(*args, fillvalue=fillvalue)
if incomplete == 'strict':
return zip(*args, strict=True)
if incomplete == 'ignore':
return zip(*args)
else:
raise ValueError('Expected fill, strict, or ignore')
Python code:
def getTuples(size):
intSize = size // 5
if size / 5 > intSize:
return (intSize + 1) * 5
else:
return intSize * 5
def convert(l):
new = []
t = ()
tValue = 0
for i in range(0, getTuples(len(l))):
tValue += 1
try:
val = l[i]
except IndexError:
val = None
if tValue == 5:
new.append(t)
t = ()
else:
t = t + (val,)
new.append(t)
L = ['ad', 'bc', 'gh', 'kj', 'ws', 'er', 'th']
L3 = list()
idx = 0
while idx < len(L):
L2 = list()
for idx2 in range(5):
L2.append(L[idx])
idx = idx +1
if idx >= len(L):
break
while idx2 < 4:
L2.append(None)
idx2 = idx2 + 1
L3.append(tuple(L2))
print(L3)