Testing an index in a for loop - Python [duplicate] - python

This question already has answers here:
How can I iterate over overlapping (current, next) pairs of values from a list?
(12 answers)
Closed 8 years ago.
Very simple problem, although I am having quite a tough time solving it.
Take a look at the code and I will explain below:
def printc(some_text):
split_text = list(some_text)
for x in split_text:
if x is '{'
# this is what i need help with
printc("{CCyan, {RRed, {YYello)
The idea behind this and it is still very early in the code development, but what I am trying to do is create an iterator that searches through "split_text" and finds the character '{' then i want to test what character is situated right next to it. How would i go about doing that?
For example is searches through split_text and finds the first { i want to see if the character next to it is either A, B, C, etc...
Any ideas?

Much easier with a single regex.
import re
re.findall('{(.)', some_text)
outputs:
['C', 'R', 'Y']

for x, y in zip(some_text, some_text[1:]):
if x == '{':
print y
you could even make it simpler:
chars = [y for (x, y) in zip(some_text, some_text[1:]) if x == '{']

I usually iterate in pairs if I need something like this:
from itertools import tee, izip
def pairwise(iterable):
"""Iterate in pairs
>>> list(pairwise([0, 1, 2, 3]))
[(0, 1), (1, 2), (2, 3)]
>>> tuple(pairwise([])) == tuple(pairwise('x')) == ()
True
"""
a, b = tee(iterable)
next(b, None)
return izip(a, b)
Usage is like:
for left, right in pairwise(iterable):
...

Related

check whether the list of strings contains all characters of another string -Python [duplicate]

This question already has answers here:
Python code that will find words made out of specific letters. Any subset of the letters could be used [duplicate]
(4 answers)
Closed 3 years ago.
S = ['cat','tor','tutorial','item','aba','tori']
T = "oti"
for item in S:
for i in item:
if i in T:
print(item)
I want to get 'tori' and 'tutorial' because those are the 2 words that contain o, t, i. The code above will print everything from the list. Using find() is not an option because there is no match.
Will using match be a good option here? I could use some hint here. Thanks in advance.
Use sets for membership testing.
>>>
>>> T = 'oti'
>>> S = ['cat','tor','tutorial','item','aba','tori']
>>> t = set(T)
>>> t
{'o', 't', 'i'}
>>> for thing in S:
... if t.issubset(thing):
print(thing)
tutorial
tori
>>>
This won't work if there are duplicate characters.
>>> q = set('otti')
>>> for thing in S:
... if q.issubset(thing):
print(thing)
tutorial
tori
>>>
Using all
>>>
>>> for thing in S:
... if all(c in thing for c in T):
print(thing)
tutorial
tori
>>>

Printing a python list with the index and items together [duplicate]

This question already has answers here:
Accessing the index in 'for' loops
(26 answers)
Closed 4 years ago.
I do understand how to achieve putting letters in a list separated by commas:
e.g.
a = 'hello'
print(list(a))
How can I achieve such an output below?
['h':0, 'e':1, 'l':2, 'l':3, 'o':4]
Use enumerate.
Your list looks like a dictionary and will make operations on it a bit tougher.
Almost close:
>>> a = 'hello'
>>> [f'{x}: {i}' for i, x in enumerate(a)]
['h: 0', 'e: 1', 'l: 2', 'l: 3', 'o: 4']
But
A better way to organise your list is to make a list of tuples as follows:
>>> [(x, i) for i, x in enumerate(a)]
[('h', 0), ('e', 1), ('l', 2), ('l', 3), ('o', 4)]
Now, you could easily iterate and perform operations on list.
outa = [(i,w) for w,i in enumerate(a)]
print(outa)
outa = dict() # gives you [("h",0),("e",1),("l",2),("l",3),("o",4)]
for w,i in enumerate(a):
outa[w] = i
print(outa) # gives you {0:"h",1:"e",2:"l",3:"l",4:"o"}
since you wrote it like a dictionary i asume you want them linked in some way or form dicitionaries cant however have dublicate keys, so i made it to a a tuple, a dicionary can however work if the key becomes the inddex and the key value the letter.
Since your output is neither a list nor a dict, you would have to format the output from a generator expression with enumerate yourself:
from pprint import pformat
print('[%s]' % ', '.join('%s:%d' % (pformat(n), i) for i, n in enumerate(a)))
This outputs:
['h':0, 'e':1, 'l':2, 'l':3, 'o':4]

Joining strings characters one after one [duplicate]

This question already has answers here:
Most pythonic way to interleave two strings
(14 answers)
Closed 4 years ago.
How to join two or more strings in python with one character after another?
For example
a = 'hello'
b = 'world'
output = 'hweolellod'
Same goes for three or more strings. using + is not helping.
You could try this:
''.join([x + y for x, y in zip(a, b)])
which gives:
'hweolrllod'
One way is to use str.join with itertools:
from itertools import chain, zip_longest
a = 'hello'
b = 'world'
zipper = zip_longest(a, b, fillvalue='')
res = ''.join(list(chain.from_iterable(zipper)))
print(res)
hweolrllod
Explanation
zip_longest is used to account for inconsistent length strings.
zipper here is a lazy iterator which iterates each character of a and b simultaneously by index.
List creation, while not necessary, is more efficient with str.join.

Python comparing two strings

Is there a function to compare how many characters two strings (of the same length) differ by? I mean only substitutions. For example, AAA would differ from AAT by 1 character.
This will work:
>>> str1 = "AAA"
>>> str2 = "AAT"
>>> sum(1 for x,y in enumerate(str1) if str2[x] != y)
1
>>> str1 = "AAABBBCCC"
>>> str2 = "ABCABCABC"
>>> sum(1 for x,y in enumerate(str1) if str2[x] != y)
6
>>>
The above solution uses sum, enumerate, and a generator expression.
Because True can evaluate to 1, you could even do:
>>> str1 = "AAA"
>>> str2 = "AAT"
>>> sum(str2[x] != y for x,y in enumerate(str1))
1
>>>
But I personally prefer the first solution because it is clearer.
This is a nice use case for the zip function!
def count_substitutions(s1, s2):
return sum(x != y for (x, y) in zip(s1, s2))
Usage:
>>> count_substitutions('AAA', 'AAT')
1
From the docs:
zip(...)
zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)]
Return a list of tuples, where each tuple contains the i-th element
from each of the argument sequences. The returned list is truncated
in length to the length of the shortest argument sequence.
Building on what poke said I would suggest the jellyfish package. It has several distance measures like what you are asking for. Example from the documentation:
IN [1]: jellyfish.damerau_levenshtein_distance('jellyfish', 'jellyfihs')
OUT[1]: 1
or using your example:
IN [2]: jellyfish.damerau_levenshtein_distance('AAA','AAT')
OUT[2]: 1
This will work for many different string lengths and should be able to handle most of what you throw at it.
Similar to simon's answer, but you don't have to zip things in order to just call a function on the resulting tuples because that's what map does anyway (and itertools.imap in Python 2). And there's a handy function for != in operator. Hence:
sum(map(operator.ne, s1, s2))

python - match on array return value

I want to do a functional like pattern match to get the first two elements, and then the rest of an array return value.
For example, assume that perms(x) returns a list of values, and I want to do this:
seq=perms(x)
a = seq[0]
b = seq[1]
rest = seq[2:]
Of course I can shorten to:
[a,b] = seq[0:2]
rest = seq[2:]
Can I use some notation to do this?
[a,b,more] = perms(x)
or conceptually:
[a,b,more..] = perms(x)
PROLOG & functional languages do list decomposition so nicely like this!
You can do it in Python 3 like this:
(a, b, *rest) = seq
See the extended iterable unpacking PEP for more details.
In python 2, your question is very close to an answer already:
a, b, more = (seq[0], seq[1], seq[2:])
or:
(a, b), more = (seq[0:2], seq[2:])
For Python 2, I know you can do it with a function:
>>> def getValues(a, b, *more):
return a, b, more
>>> seq = [1,2,3,4,5]
>>> a, b, more = getValues(*seq)
>>> a
1
>>> b
2
>>> more
(3, 4, 5)
But not sure if there's any way of doing it like Ayman's Python 3 suggestion
Very nice, thanks.
The suggestions where one dissects the array on the fight-hand side don't work so well for me, as I actually wanted to pattern match on the returns from a generator expression.
for (a, b, more) in perms(seq): ...
I like the P3 solution, but have to wait for Komodo to support it!

Categories

Resources