Issue with single line nested for loop in Python - python

I have data that exports in a string
output = '012345678910abcdefghijkl'
cleaned_output = [output[index:index + 4] for index in range(0, len(output), 4)]
cleaned_output = [cleaned_output[i][item] for i in range(0, len(cleaned_output)) for item in range(0,len(cleaned_output[i]))]
Which returns:
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '1', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l']
However, I am looking to return the below, any ideas on where I am going wrong?
[['0', '1', '2', '3'], ['4', '5', '6', '7'], ['8', '9', '1', '0'], ['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h'], ['i', 'j', 'k', 'l']]

You should just split your input into chunks of 4 and then convert them directly to lists:
cleaned_output = [list(output[i:i+4]) for i in range(0, len(output), 4)]
Output:
[['0', '1', '2', '3'], ['4', '5', '6', '7'], ['8', '9', '1', '0'], ['a', 'b', 'c', 'd'], ['e', 'f', 'g', 'h'], ['i', 'j', 'k', 'l']]

Related

Merge every certain number of items in a list

I have a list like this
items= ['e', '4', 'e', 'e', '4', '5', '4', '8', 'a', '8', '6', 'd', '8', 'a', 'e', '1', 'b', '6', '2', '1', '6', 'a', 'a', 'a', '2', 'b', 'd', '6', '7', '7', '9', '2']
I want to edit the list so that every 4 items in the list get merged like this
items=['e4ee', '4548', 'a86d', '8ae1', 'b621', '6aaa', '2bd6', '7792']
Edit: My mistake for wording. By not creating a new list I meant by putting the arranged elements into a separate list like this
items = ['e', '4', 'e', 'e', ...
items2 = ['e4ee', '4548', ...
You could do it like this although this does create a new list:
items = ['e', '4', 'e', 'e', '4', '5', '4', '8', 'a', '8', '6', 'd', '8', 'a', 'e', '1', 'b', '6', '2', '1', '6', 'a', 'a', 'a', '2', 'b', 'd', '6', '7', '7', '9', '2']
items = [''.join(items[i:i+4]) for i in range(0, len(items), 4)]
print(items)
Output:
['e4ee', '4548', 'a86d', '8ae1', 'b621', '6aaa', '2bd6', '7792']
If you absolutely do not want to create a new list (as stated):
result_len = len(items) // 4
for i in range(result_len):
j = (i*4)
items[i] = ''.join(items[j:(j+4)])
for i in range(len(items) - 1, result_len - 1, -1):
del items[i]
Does exactly len(items) iterations and never creates a new list.
The first loop updates the first result_len items in the list to the desired values. The second one deletes the rest of the items from it.
EDIT: Whoops, had a bug there. Now it should be correct.

How to format list in python

So I am trying to format a list for this:
['w', 'e', '5', 'p', '4', '7', '2', 'w']
to this:
we5p472w
Any idea how to do this?
NOTE: this is a LIST, not a STRING
Use the join() method:
l = ['w', 'e', '5', 'p', '4', '7', '2', 'w']
print (''.join(l))
Outut:
we5p472w
You can use any expression to join your list elements:
print (' '.join(l))
Output:
w e 5 p 4 7 2 w
Code:
myList = ['w', 'e', '5', 'p', '4', '7', '2', 'w']
myString = "".join(myList)
print(myString)
Output:
$ we5p472w
list1 = ['w', 'e', '5', 'p', '4', '7', '2', 'w']
print("".join(list1))
returns we5p472w
check https://www.geeksforgeeks.org/join-function-python/ for a more detail explanation and more examples

How to combine 'like' elements within nested list?

I have 3 nested lists:
STEP = [['S', '1', 'B', '3'], ['S', '3', 'B', '11'], ['S', '5', 'B', '12'], ['S', '4', 'B', '13'], ['S', '2', 'B', '14']]
TRANSITION = [['T', '2', 'B', '4'], ['T', '7', 'B', '4'], ['T', '3', 'S', '4'], ['T', '5', 'S', '5'], ['T', '1', 'S', '2'], ['T', '8', 'S', '2'], ['T', '6', 'S', '1'], ['T', '9', 'S', '2'], ['T', '4', 'S', '1'], ['T', '10', 'S', '1']]
BRANCH = [['B', '3', 'T', '1'], ['B', '3', 'T', '7'], ['B', '4', 'S', '3'], ['B', '11', 'T', '3'], ['B', '11', 'T', '5'], ['B', '12', 'T', '6'], ['B', '12', 'T', '8'], ['B', '13', 'T', '4'], ['B', '13', 'T', '9'], ['B', '14', 'T', '2'], ['B', '14', 'T', '10']]
Each element holds information as such:
# Example
STEP[0] = ['S', '1', 'B', '3']
Where:
'S' is the STEP type
'1' is the STEP number id
'B' is the linked BRANCH type
'3' is the linked BRANCH number id
Starting from a STEP the data is all linked, so using the linked reference you can find the next element and the next until another STEP is reached.
This is some parameters of the data:
STEPS are connected to single BRANCHES
BRANCHES are connected to one or more TRANSITIONS
TRANSITIONS can be connected to a single BRANCH or STEP
The BRANCH data can have a fork where a single BRANCH id has one or more options for TRANSITIONS.
I would like to combine these forks to the same `BRANCH' id, ie:
# BRANCH[0] and BRANCH[1] both have an id of '3'
# therefore, need to be combined
BRANCH[0] = ['B', '3', 'T', ['1', '7']]
This should be done to create a new list that combines all 'like' BRANCHES.
My attempt thus far (did not get very far):
for i in B:
if i[1] == B['all except current i'][1]
# append the branch id and the two transitions
I'm pretty sure there are easier ways, but based on your example, you can try :
BRANCH = [['B', '3', 'T', '1'], ['B', '3', 'T', '7'], ['B', '4', 'S', '3'], ['B', '11', 'T', '3'], ['B', '11', 'T', '5'], ['B', '12', 'T', '6'], ['B', '12', 'T', '8'], ['B', '13', 'T', '4'], ['B', '13', 'T', '9'], ['B', '14', 'T', '2'], ['B', '14', 'T', '10']]
tmp = {}
final = []
for x in BRANCH:
if not f"{x[0]}-{x[1]}" in tmp:
tmp[f"{x[0]}-{x[1]}"] = [x[3]]
else:
tmp[f"{x[0]}-{x[1]}"].append(x[3])
for k, v in tmp.items():
one, two = k.split("-")
for x in BRANCH:
if x[0] == one and x[1] == two:
if not [one, two, x[2], v] in final:
final.append([one, two, x[2], v])
print(final)
[['B', '3', 'T', ['1', '7']], ['B', '4', 'S', ['3']], ['B', '11', 'T', ['3', '5']], ['B', '12', 'T', ['6', '8']], ['B', '13', 'T', ['4', '9']], ['B', '14', 'T', ['2', '10']]]
Demo
You can use a test for similarity of the branches and then loop over the branches checking similarity. The rest is just guarding against duplicates and massaging the data to a list of lists. I did randomize the data and add another item to check that it wouldn't choke on more than a pair of similar branches.
# Check similarity (first three fields equal).
def similar_p(one, two):
for item in range(len(one) - 1):
if one[item] != two[item]:
return False
return True
# Data. Works sorted and not.
branches = [
['B', '14', 'T', '2'],
['B', '12', 'T', '6'],
['B', '14', 'T', '10'],
['B', '13', 'T', '4'],
['B', '3', 'T', '9'],
['B', '12', 'T', '8'],
['B', '13', 'T', '9'],
['B', '3', 'T', '7'],
['B', '4', 'S', '3'],
['B', '11', 'T', '5'],
['B', '3', 'T', '1'],
['B', '11', 'T', '3'],
]
merge_dict = {}
# Loop over branches. Uncomment print statements to watch the action.
for i in range(len(branches)):
# print('check for similars to branch {}'.format(branches[i]))
# try/except to ensure the dictionary item is actually there.
try:
# print(merge_dict[tuple(branches[i][0:3])])
if branches[i][3] not in merge_dict[tuple(branches[i][0:3])]:
merge_dict[tuple(branches[i][0:3])].append(branches[i][3])
# print('initial appending to branch {}'.format(branches[i]))
except (KeyError):
merge_dict[tuple(branches[i][0:3])] = [branches[i][3]]
# print('starting branch {}'.format(branches[i]))
for j in range((i + 1), len(branches), 1):
if similar_p(branches[i], branches[j]):
if branches[j][3] not in merge_dict[tuple(branches[i][0:3])]:
merge_dict[tuple(branches[i][0:3])].append(branches[j][3])
# print('appending similar branch {} to branch {}'.format(branches[j], branches[i]))
merged = list()
# Massage into a list. Sorting is on you, kid.
for k,v in merge_dict.items():
if len(v) == 1:
merged.append([*k, *v])
else:
merged.append([*k, v])
print(merged)
Output:
[['B', '14', 'T', ['2', '10']], ['B', '12', 'T', ['6', '8']], ['B', '13', 'T', ['4', '9']], ['B', '3', 'T', ['9', '7', '1']], ['B', '4', 'S', '3'], ['B', '11', 'T', ['5', '3']]]

Convert flat list to dictionary with keys at regular intervals [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have a list containing a string and lists. I should show you;
list_x = ['a', ['j', '1', 'x'], ['k', '2', 'y'], ['a', '3', 'hj'],
'd', ['b', '4', 'df'], ['c', '5', 'er'], ['d', '6', 'ty'],
'g', ['e', '7', 'hj'], ['f', '8', 'bv'], ['g', '9', 'sad'],
'j', ['h', '10', 'kj'], ['i', '11', 'nbv'], ['c', '12', 'uy'],
'n', ['d', '13', 'ipoas'], ['e', '14', 'fg'], ['f', '15', 'as'],
'r', ['g', '16', 'dsad'], ['h', '17', 'fdgdfg'], ['i', '18', 'retrt'],
'u', ['j', '19', 'qwe'], ['k', '20', 'ytgf'], ['n', '21', 'asmz']]
And I want a dict from this list like this;
dict_x = {'a': [['j', '1', 'x'], ['k', '2', 'y'], ['a', '3', 'hj']],
'd': [['b', '4', 'df'], ['c', '5', 'er'], ['d', '6', 'ty']],
'g': [['e', '7', 'hj'], ['f', '8', 'bv'], ['g', '9', 'sad']],
'j': [['h', '10', 'kj'], ['i', '11', 'nbv'], ['c', '12', 'uy']],
'n': [['d', '13', 'ipoas'], ['e', '14', 'fg'], ['f', '15', 'as']],
'r': [['g', '16', 'dsad'], ['h', '17', 'fdgdfg'], ['i', '18', 'retrt']],
'u': [['j', '19', 'qwe'], ['k', '20', 'ytgf'], ['n', '21', 'asmz']]}
Here's a straightforward solution with a simple loop:
dict_x = {}
for value in list_x:
if isinstance(value, str):
dict_x[value] = current_list = []
else:
current_list.append(value)
Basically, if the value is a string then a new empty list is added to the dict, and if it's a list, it's appended to the previous list.
Here is one way using a dictionary comprehension and a generator expression combined with * unpacking.
res = {i: j for i, *j in (list_x[i:i + 4] for i in range(0, len(list_x), 4))}
# {'a': [['j', '1', 'x'], ['k', '2', 'y'], ['a', '3', 'hj']],
# 'd': [['b', '4', 'df'], ['c', '5', 'er'], ['d', '6', 'ty']],
# 'g': [['e', '7', 'hj'], ['f', '8', 'bv'], ['g', '9', 'sad']],
# 'j': [['h', '10', 'kj'], ['i', '11', 'nbv'], ['c', '12', 'uy']],
# 'n': [['d', '13', 'ipoas'], ['e', '14', 'fg'], ['f', '15', 'as']],
# 'r': [['g', '16', 'dsad'], ['h', '17', 'fdgdfg'], ['i', '18', 'retrt']],
# 'u': [['j', '19', 'qwe'], ['k', '20', 'ytgf'], ['n', '21', 'asmz']]}
Alternatively, as #chrisz suggests, you can use zip:
res = {i: j for i, *j in zip(*(list_x[i::4] for i in range(4)))}

How do I add a suffix to the end of each list element?

I have two, unequal length lists. The first list contains variable names for a longitudinal study, the other contains suffixes for these variables. The user supplies a CSV from which the variable names are read, and then is prompted to enter the (n) number of iterations of these variables, and the names of the n number of suffixes
Here is a fake example of what I mean
Number of iterations: 2
Suffix1: pre
Suffix2: 6month
List 1:
['mood1', 'mood2', 'mood3', 'dep1', 'dep2', 'dep3']
List 2:
['pre', '6month']
Desired concatenation:
['mood1_pre', 'mood2_pre', 'mood3_pre', 'dep1_pre', 'dep2_pre', 'dep3_pre', 'mood1_6month', ..., 'dep3_6month']
I have the program working fully, except the output splits each letter of the concatenated list into its own element, for example:
How many iterations of the variables do you need?: 3
Variable Suffix 1: pre
Variable Suffix 2: 6m
Variable Suffix 3: 12m
['B', 'o', 'b', '_', 'p', 'r', 'e', 'J', 'o', 'e', '_', 'p', 'r', 'e', 'J', 'i',
'm', '_', 'p', 'r', 'e', 'A', '_', 'p', 'r', 'e', 'B', '_', 'p', 'r', 'e', 'C',
'_', 'p', 'r', 'e', '1', '_', 'p', 'r', 'e', '2', '_', 'p', 'r', 'e', '3', '_',
'p', 'r', 'e', '1', '4', '_', 'p', 'r', 'e', 'B', 'o', 'b', '_', '6', 'm', 'J',
'o', 'e', '_', '6', 'm', 'J', 'i', 'm', '_', '6', 'm', 'A', '_', '6', 'm', 'B',
'_', '6', 'm', 'C', '_', '6', 'm', '1', '_', '6', 'm', '2', '_', '6', 'm', '3',
'_', '6', 'm', '1', '4', '_', '6', 'm', 'B', 'o', 'b', '_', '1', '2', 'm', 'J',
'o', 'e', '_', '1', '2', 'm', 'J', 'i', 'm', '_', '1', '2', 'm', 'A', '_', '1',
'2', 'm', 'B', '_', '1', '2', 'm', 'C', '_', '1', '2', 'm', '1', '_', '1', '2',
'm', '2', '_', '1', '2', 'm', '3', '_', '1', '2', 'm', '1', '4', '_', '1', '2',
'm']
I am using this to make the new list
newvarlist.extend((varlist[vars] + '_' + varsuffix[j]))
Here is one way to do it using list comprehension:
['{}_{}'.format(a, b) for b in b_list for a in a_list]
Demo:
>>> a_list = ['mood1', 'mood2', 'mood3', 'dep1', 'dep2', 'dep3']
>>> b_list = ['pre', '6month']
>>> result = ['{}_{}'.format(a, b) for b in b_list for a in a_list]
>>> result
['mood1_pre', 'mood2_pre', 'mood3_pre', 'dep1_pre', 'dep2_pre', 'dep3_pre', 'mood1_6month', 'mood2_6month', 'mood3_6month', 'dep1_6month', 'dep2_6month', 'dep3_6month']
If you are flexible on the ordering of the final list:
from itertools import product, imap
l1 = ['mood1', 'mood2', 'mood3', 'dep1', 'dep2', 'dep3']
l2 = ['pre', '6month']
x = list(imap('_'.join, product(l1, l2)))
This produces ['mood1_pre', 'mood1_6month', ...] rather than ['mood1_pre', 'mood2_pre', ...].

Categories

Resources