Read python list correctly - python

I have defined a function that takes in a list like this
arr = ['C','D','E','I','M']
I have another function that produces a similar kind of list, the function is:
def tree_count(arr):
feat = ['2','2','2','2','0']
feat_2 = []
dictionary = dict(zip(arr, feat))
print('dic',dictionary)
feat_2.append([k for k,v in dictionary.items() if v=='2'])
newarr = str(feat_2)[1:-1]
print(newarr)
This outputs the correct result that I want, i.e:
['C','D','E','I']
But the problem is, when I use this list in another function, its values should be read as C,D,E,I . But instead when I print this, the bracket [ and ' are included as result:
for i in newarr:
print(i)
The printed result is : [ ' C ', and so on for each line. I want to get rid of [ '. How do I solve this?

For some reason you are using str() on the array, this is what causes the square brackets from array to appear in the print statement.
See if the following methods suit you:
print(arr) # ['C','D','E','I'] - the array itself
print(str(arr)) # "['C', 'D', 'E', 'I']" - the array as string literal
print(''.join(arr)) # 'CDEI' - array contents as string with no spaces
print(' '.join(arr)) # 'C D E I' - array contents as string with spaces

Make your function return the dictionary rather than just printing it:
def tree_count(arr):
feat = ['2','2','2','2','0']
dictionary = dict(zip(arr, feat))
dictionary = [k for k in dictionary if dictionary[k] == '2']
return dictionary
For instance,
$ results = tree_count(['C','D','E','I','M'])
$ print(results)
['I', 'C', 'D', 'E']
Pretty-printing is then fairly straightforward:
$ print("\n".join(results))
I
C
D
E
... or if you just want ,:
$ print(", ".join(results))
I, C, D, E

Related

What is the correct way to write this function?

I was making a program where first parameter is a list and second parameter is a list of dictionaries. I want to return a list of lists like this:
As an example, if this were a function call:
make_lists(['Example'],
[{'Example': 'Made-up', 'Extra Keys' : 'Possible'}]
)
the expected return value would be:
[ ['Made-up'] ]
As an second example, if this were a function call:
make_lists(['Hint', 'Num'],
[{'Hint': 'Length 2 Not Required', 'Num' : 8675309},
{'Num': 1, 'Hint' : 'Use 1st param order'}]
)
the expected return value would be:
[ ['Length 2 Not Required', 8675309],
['Use 1st param order', 1]
]
I have written a code for this but my code does not return a list of lists, it just returns a single list. Please can someone explain?
def make_lists(s,lod):
a = []
lol =[]
i = 0
for x in lod:
for y in x:
for k in s:
if(y==k):
lol.append(x.get(y))
i = i+1
return lol
Expected Output:
[ ['Length 2 Not Required', 8675309],['Use 1st param order', 1] ]
Output:
['Length 2 Not Required', 8675309, 1, 'Use 1st param order']
The whole point of dictionaries, is that you can access them by key:
def make_lists(keys, dicts):
result = []
for d in dicts:
vals = [d[k] for k in keys if k in d]
if len(vals) > 0:
result.append(vals)
return result
Let's have a look what happens here:
We still have the result array, which accumulates the answers, but now it's called result instead of lol
Next we iterate through every dictionary:
for d in dicts:
For each dictionary d, we create a list, which is a lookup in that dictionary for the keys in keys, if the key k is in the dictionary d:
vals = [d[k] for k in keys if k in d]
The specs don't detail this, but I assume if none of the keys are in the dictionary, you don't want it added to the array. For that, we have a check if vals have any results, and only then we add it to the results:
if len(vals) > 0:
result.append(vals)
Try this code - I've managed to modify your existing code slighty, and added explanation in the comments. Essentially, you just need to use a sub-list and add that to the master list lol, and then in each loop iteration over elements in lod, append to the sub-list instead of the outermost list.
def make_lists(s,lod):
a = []
lol =[]
i = 0
for x in lod:
## Added
# Here we want to create a new list, and add it as a sub-list
# within 'lol'
lols = []
lol.append(lols)
## Done
for y in x:
for k in s:
if(y==k):
# Changed 'lol' to 'lols' here
lols.append(x.get(y))
i = i+1
return lol
print(make_lists(['Example'], [{'Example': 'Made-up', 'Extra Keys' : 'Possible'}]))
print(make_lists(['Hint', 'Num'], [{'Hint': 'Length 2 Not Required', 'Num' : 8675309}, {'Num': 1, 'Hint' : 'Use 1st param order'}]))
Prints:
[['Made-up']]
[['Length 2 Not Required', 8675309], [1, 'Use 1st param order']]
A simpler solution
For a cleaner (and potentially more efficient approach), I'd suggest using builtins like map and using a list comprehension to tackle this problem:
def make_lists(s, lod):
return [[*map(dict_obj.get, s)] for dict_obj in lod]
But note, that this approach includes elements as None in cases where the desired keys in s are not present in the dictionary objects within the list lod.
To work around that, you can pass the result of map to the filter builtin function so that None values (which represent missing keys in dictionaries) are then stripped out in the result:
def make_lists(s, lod):
return [[*filter(None, map(dict_obj.get, s))] for dict_obj in lod]
print(make_lists(['Example'], [{'Extra Keys' : 'Possible'}]))
print(make_lists(['Hint', 'Num'], [{'Num' : 8675309}, {'Num': 1, 'Hint' : 'Use 1st param order'}]))
Output:
[[]]
[[8675309], ['Use 1st param order', 1]]

Add to set elements of a splitted string

I'm receiving values as strings, separated by comma.
Example:
alpha, gane, delta
delta, opsirom, nado
I want to obtain a list/set of uniques values, sorted. I'm trying to use a set for uniquenes:
app = set()
for r in result:
app = app | set(r.split[","])
but I get the following error:
TypeError: 'builtin_function_or_method' object is not subscriptable
I would use a mix between split and replace if I'm understand your input correctly and set for uniqueness as you stated:
value_1 = "alpha, gane, delta, alpha"
aux_1 = value_1.replace(" ","").split(",")
a = list(set(aux_1))
print(a)
#Another list formatted as string arrives:
value_2 = "alpha, beta, omega, beta"
aux_2 = value_2.replace(" ","").split(",")
#Option 1:
a += list(set(aux_2))
a = list(set(a))
print(a)
#Option 2:
for i in aux_2:
if i in a:
pass
else:
a.append(i)
print(a)
Output for both cases:
['delta', 'gane', 'omega', 'beta', 'alpha']
After you receive another string you can add the values to the full list, in this case a and use set() again to eliminate further duplicates. Or check for each individual value if the the value in the string is in the full list and append it if it's not, or skip if it already exists in the full list.
as well as you can use below code,
splited_inputs = inputs.split(',')
unique_values = list(dict.fromkeys(splited_inputs))
Try this:
s = "alpha, gane, delta, delta, opsirom, nado"
unique_values = list(set(s.rsplit(', ')))
print(unique_values)
outputs:
['opsirom', 'delta', 'alpha', 'gane', 'nado']
You are not too far off. The immediate problem was the use of [] instead of () for the split function call.
In [151]: alist = """alpha, gane, delta
...: delta, opsirom, nado""".splitlines()
In [152]: alist
Out[152]: ['alpha, gane, delta', 'delta, opsirom, nado']
In [153]: aset = set()
In [154]: for astr in alist:
...: aset |= set(astr.split(', '))
...:
In [155]: aset
Out[155]: {'alpha', 'delta', 'gane', 'nado', 'opsirom'}
The use | to join sets is fine; I used the \= version. The split delimiter needed to be tweaked to avoid having both 'delta' and ' delta' in result. Otherwise you might need to apply strip to each string. #Victor got this part right.

Is there a python code for finding the combination of a row with only some colums are variable

I have a row of string data like:
A, B, C/D , E/F, J , K
I want to find the non repeating combination of whole row where only column data containing "/" undergo combination (python code 3.x )
Output:
A,B,C,E,J,K
A,B,D,E,J,K
A,B,C,F,J,K
A,B,D,F,J,K
Single Items are constant columns. It is preferable if the code works with N number of columns and m number of items within each variable colums. Please help
I could not use any of python builtin methods directly to solve this.
You mean something like this?
from itertools import product
s = ['A', 'B', 'C/D', 'E/F', 'J', 'K']
s = [x.split('/') for x in s]
for p in product(*s):
print(''.join(p))
Output
ABCEJK
ABCFJK
ABDEJK
ABDFJK
Here is the code to compute the answer recursively:
def _compute_result(arr, i, prefix, results):
if i == len(arr):
results.append(','.join(prefix))
return
for j in arr[i].split('/'):
_compute_result(arr, i + 1, prefix + [j], results)
string_array = input().strip().split(' ')
results = []
_compute_result(string_array, 0, [], results)
print(' '.join(results))
O/P:
A,B,C,E,J,K A,B,C,F,J,K A,B,D,E,J,K A,B,D,F,J,K

Iterating through a dictionary of lists and returning the character at the same index

Working on printing a vertical column from a matrix passed as a string.
I've created a dictionary and assigned each row of the matrix as a value in the dict then bracketed to create a dictionary of lists.
Would like to iterate through each key in the dict and append the value of the given index (e.g. if value is 'a b c', return 'a' for 1, ' ' for 2...) but all I keep getting is:
[['a b c '], ['a b c '], ['a b c ']]
Or variations on this when I fiddle with it. It never seems to get past row 1, although each value is clearly a different row in the matrix.
Appreciate any help.
def column (str, index):
output = []
li = str.split("\n")
row_dict = {
1: [li[0]],
2: [li[1]],
3: [li[2]]
}
for key in row_dict:
output.append(row_dict[index])
return output
str = "a b c \n d e f \n g h i"
column(str, 1)
First, split on "\n " because you seem to have a whitespace after each newline.
Getting the nth item of each row is pretty straightforward if you use list comprehensions, e.g. [row[index] for row in s.split("\n ")].
Altogether:
>>> def column (s, index):
return [row[index] for row in s.split("\n ")]
>>> s = "a b c \n d e f \n g h i"
>>> column(s, 1)
[' ', ' ', ' ']
Or, if you want it to be 1-indexed (like in the example in the question) instead of 0-indexed:
>>> def column (s, index):
return [row[index-1] for row in s.split("\n ")]
>>> s = "a b c \n d e f \n g h i"
>>> column(s, 1)
['a', 'd', 'g']
As far as I can see, the only issue with your code is that you are appending the dictionary value (which is a row, and not the actual value, for example it is getting the row at key = 'index', rather than the value at location 'index' in each of the dictionaries) to output, when you want to assign a particular value from each row... this is what you should be doing:
for key in row_dict:
output.append(row_dict[key].split()[index])
print (row_dict[key].split()[index])
For index=1, this will print:
b
e
h
This does three things in one statement:
gets the string stored at key='key' from dictionary
splits your string into individual characters (so you can extract them more easily)
Gets the character/word at the index specified by your parameters.
You probably forgot to mention the key on which you were iterating. Your function should be something like:
def column(str, index):
output = []
li = str.split("\n")
row_dict = {
1: li[0].lstrip().split(' '),
2: li[1].strip().split(' '),
3: li[2].strip().split(' ')
}
for key in row_dict:
output.append(row_dict[key][index])
return output
Also, note that you were adding extra [] to the values of the row_dict. Finally, iterable objects in Python start from a 0th index, so you would call your function like column("a b c \n d e f \n g h i", 0).
Hope it helps.

Converting strings within a list into floats

I have a list of numerical values that are of type "string" right now. Some of the elements in this list have more than one value, e.g.:
AF=['0.056', '0.024, 0.0235', '0.724', '0.932, 0.226, 0.634']
The other thing is that some of the elements might be a .
With that being said, I've been trying to convert the elements of this list into floats (while still conserving the tuple if there's more than one value), but I keep getting the following error:
ValueError: could not convert string to float: .
I've tried a LOT of things to solve this, with the latest one being:
for x in AF:
if "," in x: #if there are multiple values for one AF
elements= x.split(",")
for k in elements: #each element of the sub-list
if k != '.':
k= map(float, k)
print(k) #check to see if there are still "."
else:
pass
But when I run that, I still get the same error. So I printed k from the above loop and sure enough, there were still . in the list, despite me stating NOT to include those in the string-to-float conversion.
This is my desired output:
AF=[0.056, [0.024, 0.0235], 0.724, [0.932, 0.226, 0.634]]
def convert(l):
new = []
for line in l:
if ',' in line:
new.append([float(j) for j in line.split(',')])
else:
try:
new.append(float(line))
except ValueError:
pass
return new
>>> convert(AF)
[0.056, [0.024, 0.0235], 0.724, [0.932, 0.226, 0.634]]
If you try this:
result = []
for item in AF:
if item != '.':
values = list(map(float, item.split(', ')))
result.append(values)
You get:
[[0.056], [0.024, 0.0235], [0.724], [0.932, 0.226, 0.634]]
You can simplify using a comprehension list:
result = [list(map(float, item.split(', ')))
for item in AF
if item != '.']
With re.findall() function (on extended input list):
import re
AF = ['0.056', '0.024, 0.0235, .', '.', '0.724', '0.932, 0.226, 0.634', '.']
result = []
for s in AF:
items = re.findall(r'\b\d+\.\d+\b', s)
if items:
result.append(float(items[0]) if len(items) == 1 else list(map(float, items)))
print(result)
The output:
[0.056, [0.024, 0.0235], 0.724, [0.932, 0.226, 0.634]]

Categories