Removing from a list without affecting a dummy variable - python

from random import choice
inputs=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0']
func={}
code=""
z=len(inputs)
x=z-1
temp=inputs
while x>=0:
y=choice(temp)
print(str(x)+" "+inputs[x]+" "+y)
func[inputs[x]]=y
code=code+inputs[x]+y
del temp[x]
x=x-1
print(temp)
print(inputs)
Why does this code not asign every element of inputs to a unique and random element of inputs(as the temp dummy set)? it seems to delete items from both temp and inputs when only told to delete items from the dummy set.
Thanks for any help.

You are not making a copy of 'inputs' when you do 'temp=inputs', but making a new variable to access the same content. If you want a new copy of the list, then use 'temp = inputs[:]'. Otherwise you are just creating a new reference to the same object, but not duplicating the object itself.
You can find more about this in the official Python FAQ.

You are creating an alias of your list instead of a true copy of it:
replace temp=inputs with temp=inputs[:]
import random
inputs = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0']
func = {}
code = ""
z = len(inputs)
x = z-1
temp = inputs[:] #<-- here
while x >= 0:
y = random.choice(temp)
print(str(x) + " " + inputs[x] + " " + y)
func[inputs[x]] = y
code = code+inputs[x] + y
del temp[x]
x = x - 1
print(temp)
print(inputs)

Related

Python: How to create a list that has duplicates of itself, but inside the previous one?

I'm trying to create a list that's inside another list and so on.
Example:
[[[]]]
becomes
[[[[]]]]
Here is my code:
startlist = []
def add_seq(list):
try:
list.append([])
except:
startlist.append([])
return startlist
else:
return list
add_seq(startlist)
print(startlist)
add_seq(startlist[-1])
print(startlist)
add_seq(startlist[-1][-1])
print(startlist)
But, I want to use the function in a loop, and the index changes (startlist[-1] becomes startlist[-1][-1])
Is there a way to change the index so that I can add more lists to the list?
I would construct the nesting layers as string and then evaluate the expression. You can store each layer in a results list to be easily accessible afterwards:
"""
Example:
r[0] - [3]
r[1] - [[3]]
r[2] - [[[3]]]
"""
import ast
start = [3]
depth = 3
r = []
for level in range(depth):
r.append(ast.literal_eval('[' * level + str(start) + ']' * level))
print(r[level])

colab keeps on crashing after using the 'GLOBAL' keyword

I copied this program from stackoverflow and added the global keyword to know the length of the list and it crashed because the ram is full.Why?If I removed the Global key word it works fine.I just wanted to know why it keeps on crashing
def permutation(s):
if len(s) == 1:
return [s]
global per_list
per_list = []
for i in s:
rm = [x for x in s if x != i]
ff = permutation(rm)
for j in ff:
per_list.append([i] + j)
return per_list
s = [3,4,5]
permutation(s)
print(len(per_list))
Declare it as empty list outside the function first and try again.
// like this
per_list = []
def permutation(s):
//body
s = [3,4,5]
permutation(s)
print(len(per_list))

Dropping Empty Lists from Nested List

So I have a function which returns a List which contains either empty lists or Series. I loop through a list of tickers and for each it will return a empty list or Series and store them inside one list.
However, after looping through all I want to be able to drop the empty lists and only have the Series within the list.
def get_revenue_growth(ticker) -> pd.DataFrame:
income_statement_annually = fa.financial_statement_growth(ticker, FA_API_KEY, period="annual")
if 'revenueGrowth' in income_statement_annually.index:
revenue_growth = income_statement_annually.loc['revenueGrowth']
exchange_df = pd.DataFrame({ticker : revenue_growth})
exchange_df.index = pd.to_datetime(pd.Series(exchange_df.index))
exchange_df = exchange_df[exchange_df.index.year >= 1998]
exchange_df = exchange_df.sort_index()
print('Getting Revenue Growth for ' + ticker + ': Passed')
else:
print('Getting Revenue Growth for ' + ticker + ': Failed')
exchange_df = []
return exchange_df
This is the function I am calling via this:
revenue_growth = [get_revenue_growth(t) for t in tickers]
Here is what the output looks like...
So what I am trying to achieve is to remove all the empty lists. I tried this list2 = [x for x in list1 if x != []] but it did not work.
You can simply solve it via:
list2 = [x for x in list1 if len(x)>0]
Look at this Example -
mylist = []
if len(mylist) == 0:
del mylist # Deletes the Empty List
else:
# Do Something else
Modify this piece for your program

Why this Python "loop code" does not work?

Why this code does not work?
ffi5_1 = pd.read_csv('/Users/d/bm_ffi5_1.csv')
ffi5_2 = pd.read_csv('/Users/d/bm_ffi5_2.csv')
ffi5_3 = pd.read_csv('/Users/d/bm_ffi5_3.csv')
ffi5_4 = pd.read_csv('/Users/d/bm_ffi5_4.csv')
ffi5_5 = pd.read_csv('/Users/d/bm_ffi5_5.csv')
s_list = list(range(1,6))
for x in s_list:
ffi5_x.jdate = pd.to_datetime(ffi5_x.jdate)
Here jdate is the column of dataframe.
Your code probably fails with a message that you attempt to refer to
a non-existing variable ffi5_x.
In order to replace x in the DataFrame name with the current value
of x - loop control variable (in 2 places), change your loop to:
for x in s_list:
exec('ffi5_' + str(x) + '.jdate = pd.to_datetime(ffi5_' + str(x) + '.jdate)')

Another IndexError with python

This is supposed to become a random name generator in the end, all the random part is working. Only problem is that it is REALLY random, getting weird stuff like aaaaaaaa etc.
So I'm trying to add a rule to not allow 2 vowels after each other (same goes with consonants).
So yeah, guys please help me out here. I've been looking throu' this code for 2 hours now and I cant find the problem.
Just pasting my entire code here.
import random
import string
import numpy as np
from sys import argv
import csv
# abcdefghijklmnopqrstuvwxyz
# Example output: floke fl0ke flok3 fl0k3
#
class facts:
kons = list('bcdfghjklmnpqrstvwxz') #20
voks = list('aeiouy') #6
abc = list('abcdefghijklmnopqrstuvwxyz')
def r_trfa(): #True Or False (1/0)
x = random.randrange(0, 2)
return x;
def r_kons(): #Konsonant
y = random.randrange(0, 20)
x = facts.kons[y]
return x;
def r_vok(): #Vokal
y = random.randrange(0, 6)
x = facts.voks[y]
return x;
def r_len(): #Langd
x = random.randrange(4, 8)
return x;
def r_type():
x = random.randrange(1, 4)
return x;
def r_structure(length): #Skapar strukturen
y = r_type()
if y == 0:
no1 = 1
else:
no1 = 2
i = 0
x = [no1]
y = r_type()
if not no1 == y:
x.append(y)
while i < length:
y = r_type()
if not x[i] == y:
x.append(y)
i = i + 1
x2 = list(x)
return x2;
def name(): #Final product
struct = r_structure(r_len())
name = struct
You've got several bugs. For example, you're checking the value y against 0 even though it is always in the range 1-4, probably unintended behavior. Furthermore, you never actually call a function that gets you a character, and you never create a string. Thus it's not clear what you're trying to do.
Here's how I'd rewrite things based on my guess of what you want to do.
import random, itertools
voks = frozenset('aeiouy')
abc = 'abcdefghijklmnopqrstuvwxyz'
def r_gen():
last=None #both classes ok
while 1:
new = random.choice(abc)
if (new in voks) != last:
yield new
last = (new in voks)
def name(): #Final product
length = random.randrange(4, 8)
return ''.join(itertools.islice(r_gen(), length))
The problem you're having is that your loop increments i always, but only adds an additional value to your x list if the random value doesn't match x[i]. This means that if you get several matches in a row, i may become larger than the largest index into x and so you'll get an IndexError exception.
I'm not entirely sure I understand what you're trying to do, but I think this will do something similar to your current r_structure function:
def r_structure(length):
"""Returns a list of random "types", avoiding any immediate repeats"""
x = [r_type()]
while len(x) < length:
y = r_type()
if y != x[-1]: # check against the last item in the list
x.append(y)
return x
If your goal is simply to randomly generate a sequence of alternating vowels and consonants, there's an easier way than what you seem to be doing. First off, you can use random.choice to pick your characters. Further, rather than picking many letters and rejecting ones that are of the wrong type, you can simply pick from one string, then pick from the other, for as long as you need:
import random
def alternating_characters(length):
characters = ["aeiouy", "bcdfghjklmnpqrstvwxz"]
char_type = random.randrange(2) # pick a random letter type to start with
results = []
while len(char_list) < length:
results.append(random.choice(characters[char_type])) # pick random char
char_type = 1-char_type # pick from the other list next time
return "".join(char_list)
Well it's unclear what you want to do.. As the conditions on vowels and consonants is the same, so why do you need to differentiate between them?
So all you need to do is take a random letter and check that it doesn't match with the last letter.
Here's some code:
import random
abc = 'abcdefghijklmnopqrstuvwxyz'
def gen_word(length):
last = ''
while length > 0:
l = random.choice(abc)
if l != last:
length -= 1
yield l
if __name__ == '__main__':
word = ''.join(gen_word(10))
print word

Categories