Tuples screwing with me - python-3.x

I'm trying to append everything but 'A' from tuple into new_tuple
>>> tuple=('A', 'B', 'C', 'D')
>>> for i in tuple:
new_tuple=()
if i!='A':
new_tuple+=(i,)
>>> new_tuple
('D',)
It only prints ('D',) instead of ('B','C','D')
But it's funny how you can loop through every element and print it....
>>> for i in tuple:
print (i)
A
B
C
D

You reinitialize new_tuple through each iteration. Put new_tuple=() before the loop and it should work.
tuple = ('A', 'B', 'C', 'D')
new_tuple = ()
for i in tuple:
if i != 'A':
new_tuple += (i,)
print new_tuple

Related

Replace multiple elements in a list with a single element

I want to replace two or more elements with a single element in a list like this:
mylist=['a','b','c']
Now I want to replace 'a' and 'b' elements with another element 'z'.
So output should be:
['z','z','c']
a list-comprehension an option:
mylist = ['a', 'b', 'c']
new_list = [x if x not in "ab" else "z" for x in mylist]
print(new_list) # ['z', 'z', 'c']
if the elements you want to replace are more complicated you could try:
if x not in {"a", "b"}
if you want to change things based on the index i you can use enumerate:
new_list = [x if i >= 2 else "z" for i, x in enumerate(mylist)]
print(new_list) # ['z', 'z', 'c']
but then you could consider slicing:
new_list = 2 * ["z"] + mylist[2:]

why this python function return len=7 instead of len=6?

I got this code below, but even debugging it, I cannot understand why gives me out 7 instead of 6.
More precisely when I debudg every return gives me the expected result:
first func call: ipdb> --Return-- ['a']
second func call: ipdb> --Return-- ['a', 'a']
third func call: ipdb> --Return-- ['a', 'a', 'a']
but at the end func() + func() + func() becomes ['a', 'a', 'a', 'a', 'a', 'a', 'a']
why is there one 'a' more???
#!/usr/bin/python
# -*- coding: utf-8 -*-
def func(par=[]):
par.append("a")
return par
print(len(func() + func() + func()))
When executing func() + func() + func(), Python has to store the temporary objects on the stack to add them together, it means that your code is equivalent to
a = func() # returns ['a']
b = func() # returns ['a', 'a'], but variable 'a' now holds ['a', 'a'] as well!
tmp = a + b
c = func() # return ['a', 'a', 'a']
d = tmp + c
return d
Because of the Mutable Default Argument, before actually adding a+b, both a and b are equal to ['a', 'a'], giving you ['a', 'a', 'a', 'a'], 4 elements, then you add ['a','a','a'] you got from the 3rd func() call, and you get 7 elements as a result.

Function doesn't change value, when applied to nested list

I have a function which iterates over list of lists. If it finds the value, which is a list itself, it should create a string from this value and insert it instead of the original one:
def lst_to_str(lst):
for x in lst:
for y in x:
i = 0
if type(y) == list:
x[i] = ",".join(y)
i +=1
return lst
The problem is, when I apply this function to pd.DataFrame column
df['pdns'] = df['pdns'].apply(lambda x: lst_to_str(x))
It returns me the original nested list:
[['a', 'b', 'c', 'd'], ['a1', 'b1', 'd1', 'c1'],['a2', 'b2', 'c2', ['d2_1', 'd2_2']]]
Instead of:
[['a', 'b', 'c', 'd'], ['a1', 'b1', 'd1', 'c1'],['a2', 'b2', 'c2', 'd2_1, d2_2']]
Your code is wrong. In your function definition, you're not making any change to 1st and in the end you return 1st. You're checking some condition and then you change the value of your counter (x). Correct this problem and try again

Python3 toggle between two strings

Is there a more elegant way to toggle between two strings or integers in Python 3?
x={"A":"B", "B":"A"}[x]
The values can be non-boolean, like string or integer.
Let's suppose that we want to toggle between "A" and "B" and the variable name is x.
In other words: if x = "A" then the result should be x = "B" and if x = "B" then the result should be x = "A".
input:
x="B"
output:
x="A"
Using a dict is already pretty smart. Here is an alternative:
x = 'B' if x == 'A' else 'A'
You can write something like that:
def toggle(x):
x['A'], x['B'] = x['B'], x['A']
x = {'A': 'B', 'B': 'A'}
or that:
def toggle(x):
x.update(dict(zip(x.keys(), list(x.values())[::-1])))
x = {'A': 'B', 'B': 'A'}
print(x)
toggle(x)
print(x)
toggle(x)
print(x)
OUTPUT:
{'A': 'B', 'B': 'A'}
{'A': 'A', 'B': 'B'}
{'A': 'B', 'B': 'A'}

Generating all the covering substrings of a string

How do you the following: given a string, generate all the possible ways to parse that string into substrings (time is important, space dont' care).
For example, given the string ABCD, I need to generate:
ABCD
A BCD
A BC D
A B CD
AB CD
AB C D
ABC D
A B C D
Probably a recursive solution, but I can't quite get it to work.
Another solution in Python, without recursion:
def substrings(s):
for k in xrange(1, len(s)+1):
for i in xrange(len(s)-k+1):
yield s[i:i+k]
so that
>>> print list(substrings("ABCD"))
['A', 'B', 'C', 'D', 'AB', 'BC', 'CD', 'ABC', 'BCD', 'ABCD']
Python:
def splitstring(s):
result = [s]
for i in range(1, len(s)):
result.extend('%s %s' % (s[:i], x) for x in splitstring(s[i:]))
return result
To get a particular split:
First, decide at which indices to split;
Then, split the string at the given indices.
For a string of length n, a given set of split indices is an element of the powerset of {1, ..., n}.
In python:
from itertools import combinations, chain
def powerset(iterable):
"powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
def pairs(seq, end):
"pairs([13,23,33], 55) --> (0,13) (13,23) (23,33) (33,55)"
return zip(chain((0,), seq), chain(seq, (end,)))
def allsplits(s):
"allsplits('abc') --> ['abc'] ['a', 'bc'] ['ab', 'c'] ['a', 'b', 'c']"
for split_indices in powerset(range(1,len(s))):
yield [s[i:j] for i,j in pairs(split_indices, len(s))]
print(list( allsplits('abcd') ))
# [['abcd'], ['a', 'bcd'], ['ab', 'cd'], ['abc', 'd'], ['a', 'b', 'cd'], ['a', 'bc', 'd'], ['ab', 'c', 'd'], ['a', 'b', 'c', 'd']]

Resources