tuple = ('e', (('f', ('a', 'b')), ('c', 'd')))
how to get the positions: (binary tree)
[('e', '0'), ('f', '100'), ('a', '1010'), ('b', '1011' ), ('c', '110'), ('d', '111')]
is there any way to indexOf ?
arvore[0] # = e
arvore[1][0][0] # = f
arvore[1][0][1][0] # = a
arvore[1][0][1][1] # = b
arvore[1][1][0] # = c
arvore[1][1][1] # = d
You need to traverse the tuple recursively (like tree):
def traverse(t, trail=''):
if isinstance(t, str):
yield t, trail
return
for i, subtree in enumerate(t): # left - 0, right - 1
# yield from traverse(subtree, trail + str(i)) in Python 3.3+
for x in traverse(subtree, trail + str(i)):
yield x
Usage:
>>> t = ('e', (('f', ('a', 'b')), ('c', 'd')))
>>> list(traverse(t))
[('e', '0'), ('f', '100'), ('a', '1010'), ('b', '1011'), ('c', '110'), ('d', '111')]
BTW, don't use tuple as a variable name. It shadows builtin type/function tuple.
Related
I was writing a class, in which there's a method with local args.
class GlobalAssign:
def __init__(self, seq1, seq2, d=-5, mismatch=-5, trans=-7):
self.seq1 = list(seq1)
self.seq2 = list(seq2)
self.mismatch = mismatch
self.d = d
self.trans = trans
def score(self, a, b):
# score for any pair of bases
pair = (str(a).capitalize(), str(b).capitalize())
if pair in {('A', 'G'), ('G', 'A'), ('C', 'T'), ('T', 'C')}:
return self.mismatch
if pair in {('A', 'C'), ('C', 'A'), ('T', 'G'), ('G', 'T'),
('A', 'T'), ('T', 'A'), ('C', 'G'), ('G', 'C')}:
return self.trans
elif a == '-' or b == '-':
return self.d
And I run following codes in the terminal:
In [62]: test = GlobalAssign('agcg','gtat')
In [63]: test.score('a','g')
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-63-f387aa9ccad8> in <module>
----> 1 test.score('a','g')
~/data/needleman.py in score(self, a, b)
11 def score(self, a, b):
12 # score for any pair of bases
---> 13 pair = (str(a).capitalize(), str(b).capitalize())
14 if pair in {('A', 'G'), ('G', 'A'), ('C', 'T'), ('T', 'C')}:
15 return self.mismatch
AttributeError: 'GlobalAssign' object has no attribute 'a'
I think a and b are local variables so I don't need to write self.a. But it raised this error and I'm a bit confused.Have been stuck for a while. Thanks if you could help me figure it out.
I've just run your code in locally and it is working; it gives me the output of -5.
I have made some adjustment to your code in order to get all the cases:
class GlobalAssign:
def __init__(self, seq1, seq2, d=-5, mismatch=-5, trans=-7):
self.seq1 = list(seq1)
self.seq2 = list(seq2)
self.mismatch = mismatch
self.d = d
self.trans = trans
def score(self, a, b):
# score for any pair of bases
pair = (str(a).capitalize(), str(b).capitalize())
if pair in [('A', 'G'), ('G', 'A'), ('C', 'T'), ('T', 'C')]:
return self.mismatch
elif pair in [('A', 'C'), ('C', 'A'), ('T', 'G'), ('G', 'T'),
('A', 'T'), ('T', 'A'), ('C', 'G'), ('G', 'C')]:
return self.trans
elif a == '-' or b == '-':
return self.d
else:
print("Value not correct.")
return None
Moreover i have removed the bracket {} and replaced with [] inside the score method.
Let me know if this help you.
Let's assume there is a list of tuples:
for something in x.something()
print(something)
and it returns
('a', 'b')
('c', 'd')
('e', 'f')
('g', 'h')
('i', 'j')
And I have created two other lists containing certain elements from the x.something():
y = [('a', 'b'), ('c', 'd')]
z = [('e', 'f'), ('g', 'h')]
So I want to assign the tuples from x.something() to a new list based on y and z by
newlist = []
for something in x.something():
if something in 'y':
newlist.append('color1')
elif something in 'z':
newlist.append('color2')
else:
newlist.append('color3')
What I would like to have is the newlist looks like:
['color1', 'color1', 'color2', 'color2', 'color3']
But I've got
TypeError: 'in <string>' requires string as left operand, not tuple
What went wrong and how to fix it?
I think you want to get if something in y instead of if something in 'y' because they are two seperate lists, not strings:
newlist = []
for something in x.something():
if something in y:
newlist.append('color1')
elif something in z:
newlist.append('color2')
else:
newlist.append('color3')
You should remove the quotes from if something in 'y' because it assumes that you're checking if something is in the string 'y'. Same for z.
try this:
t = [('a', 'b'),
('c', 'd'),
('e', 'f'),
('g', 'h'),
('i', 'j')]
y = [('a', 'b'), ('c', 'd')]
z = [('e', 'f'), ('g', 'h')]
new_list = []
for x in t:
if x in y:
new_list.append('color1')
elif x in z:
new_list.append('color2')
else:
new_list.append('color3')
print(new_list)
output:
['color1', 'color1', 'color2', 'color2', 'color3']
I am using python regular expressions. I want all colon separated values in a line.
e.g.
input = 'a:b c:d e:f'
expected_output = [('a','b'), ('c', 'd'), ('e', 'f')]
But when I do
>>> re.findall('(.*)\s?:\s?(.*)','a:b c:d')
I get
[('a:b c', 'd')]
I have also tried
>>> re.findall('(.*)\s?:\s?(.*)[\s$]','a:b c:d')
[('a', 'b')]
The following code works for me:
inpt = 'a:b c:d e:f'
re.findall('(\S+):(\S+)',inpt)
Output:
[('a', 'b'), ('c', 'd'), ('e', 'f')]
Use split instead of regex, also avoid giving variable name like keywords
:
inpt = 'a:b c:d e:f'
k= [tuple(i.split(':')) for i in inpt.split()]
print(k)
# [('a', 'b'), ('c', 'd'), ('e', 'f')]
The easiest way using list comprehension and split :
[tuple(ele.split(':')) for ele in input.split(' ')]
#driver values :
IN : input = 'a:b c:d e:f'
OUT : [('a', 'b'), ('c', 'd'), ('e', 'f')]
You may use
list(map(lambda x: tuple(x.split(':')), input.split()))
where
input.split() is
>>> input.split()
['a:b', 'c:d', 'e:f']
lambda x: tuple(x.split(':')) is function to convert string to tuple 'a:b' => (a, b)
map applies above function to all list elements and returns a map object (in Python 3) and this is converted to list using list
Result
>>> list(map(lambda x: tuple(x.split(':')), input.split()))
[('a', 'b'), ('c', 'd'), ('e', 'f')]
I have a list if items/ tuples which contain sets like this:
a_list = [(a, {x}), (b, {y}), (c, {y,z}), (d, {y,z}), (e, {x,y}), (f, {x,y,z})]
And a sample pattern:
pattern = {x,y}
Given a number of draws i would like to generate a sequence of items from a_list that fits the pattern most. The pattern shall be fulfilled with the second part of the tuple, the set.
Example:
A result with draws = 2 could be:
result = [(a, {x}), (b, {y})]
# x, y
or
result = [(e, {x,y}), (a, {x})]
# x, y
or
result = [(e, {x,y}), (b, {y})]
# x, y
Both cases fulfill the pattern {x,y} within 2 draws.
A result with draws = 1 could only be:
result = (e, {x,y})
# x, y
since there is only one draw to fulfill the pattern and only item e matches the pattern totally.
A result with draws = 7 could be:
result = [(a, {x}), (b, {y}), (e, {x,y}), (f, {x,y,z}), (c, {y,z})]
# x, y, x, y, x, y, y
Can such a function be accomplished and if, how?
Thanks for your help!
Muffin
If what i understood from your question and your comments is correct, the function below should give you the right output/print and should be equal to what you've expected in your question.
Here is my solution
from itertools import groupby
from random import randint
a_list = [
('a', {'x'}), ('b', {'y'}),
('c', {'y','z'}), ('d', {'y','z'}),
('e', {'x','y'}), ('f', {'x','y','z'})
]
pattern = {'x', 'y'}
def seq_gen(a=[], pattern=set(), draws=0):
single, multi = [], []
for i in a:
if len(i[1]) == 1:
single.append(i)
else:
multi.append(i)
final = [
j for j in single
if list(pattern)[0] in j[1]
or list(pattern)[1] in j[1]
]
final += [j for j in multi if pattern == j[1]]
if draws == 1:
for i in final:
if len(i[1]) == 2:
# for better use, return a list not a tuple
return "draw(1) => {0}".format([i])
if draws > len(final):
k, f = list(), tuple()
for _, v in groupby(a, lambda x: x[1]):
k += list(v)[0]
return "draw({0}) => {1}".format(
draws,
[tuple(k[x:x+2]) for x in range(0,len(k), 2)]
)
if draws == len(final):
return "draw({0}) => {1}".format(draws, final)
else:
aa = []
while len(aa) != 2:
element = final[randint(0, len(final) -1)]
if element not in aa:
aa.append(element)
return "draw({0}) => {1}".format(draws, aa)
for i in range(1,8):
print(seq_gen(a_list, pattern, i))
Output:
draw(1) => [('e', {'x', 'y'})]
draw(2) => [('e', {'x', 'y'}), ('a', {'x'})]
draw(3) => [('a', {'x'}), ('b', {'y'}), ('e', {'x', 'y'})]
draw(4) => [('a', {'x'}), ('b', {'y'}), ('c', {'z', 'y'}), ('e', {'x', 'y'}), ('f', {'x', 'z', 'y'})]
draw(5) => [('a', {'x'}), ('b', {'y'}), ('c', {'z', 'y'}), ('e', {'x', 'y'}), ('f', {'x', 'z', 'y'})]
draw(6) => [('a', {'x'}), ('b', {'y'}), ('c', {'z', 'y'}), ('e', {'x', 'y'}), ('f', {'x', 'z', 'y'})]
draw(7) => [('a', {'x'}), ('b', {'y'}), ('c', {'z', 'y'}), ('e', {'x', 'y'}), ('f', {'x', 'z', 'y'})]
PS: Don't hesitate to return your feedbacks. If there is something wrong i'll try to fix it with your new queries.
How could i find the the set of tuples of string?
For example there is a list of [('a', 'b'), ('b', 'a'), ('c','d')]
For me ('a', 'b') is same to ('b', 'a') . Is there any function in
python which can identify and remove one of them?
Just sort your tuples:
unique = set(tuple(sorted(t)) for t in inputlist)
Demo:
>>> inputlist = [('a', 'b'), ('b', 'a'), ('c','d')]
>>> set(tuple(sorted(t)) for t in inputlist)
set([('a', 'b'), ('c', 'd')])
You could extend collections.MutableSet() (collections.abc.MutableSet in Python 3) to encapsulate that behaviour:
try:
# Python 3
from collections.abc import MutableSet
except ImportError:
# Python 2
from collections import MutableSet
class SortingSet(MutableSet):
def __init__(self, values):
self._values = set()
for v in values:
self.add(v)
def __repr__(self):
return '<{}({}) at {:x}>'.format(
type(self).__name__, list(self._values), id(self))
def __contains__(self, value):
return tuple(sorted(value)) in self._values
def __iter__(self):
return iter(self._values)
def __len__(self):
return len(self._values)
def add(self, value):
self._values.add(tuple(sorted(value)))
def discard(self, value):
self._values.discard(tuple(sorted(value)))
Demo:
>>> inputlist = [('a', 'b'), ('b', 'a'), ('c','d')]
>>> sset = SortingSet(inputlist)
>>> sset
<SortingSet([('a', 'b'), ('c', 'd')]) at 106b74c50>
>>> ('d', 'c') in sset
True
How about:
list_ = [('a', 'b'), ('b', 'a'), ('c','d')]
set_ = set(frozenset(tuple) for tuple in list_)
print(set_)
? Tested on CPython 3.4.
The answers so far do not preserve order at all, if that is important to you then use this:
>>> from collections import OrderedDict
>>> items = [('a', 'b'), ('b', 'a'), ('c','d')]
>>> OrderedDict((frozenset(x), x) for x in items).values()
[('b', 'a'), ('c', 'd')]
This keeps the order and you said you could remove one of the duplicates (which it keeps the last)
Also the answers given so far also alter the elements:
>>> set(tuple(sorted(t)) for t in [('b', 'a'), ('c', 'd')])
set([('a', 'b'), ('c', 'd')])
>>> set(frozenset(tuple) for tuple in [('b', 'a'), ('c', 'd')])
set([frozenset(['a', 'b']), frozenset(['c', 'd'])])
This will keep the elements the same
>>> OrderedDict((frozenset(x), x) for x in [('b', 'a'), ('c', 'd')]).values()
[('b', 'a'), ('c', 'd')]