I'm trying to remove every nth number from a list in a for loop, but something's gone wrong
There's a variable that determines what numbers to remove
If I had a list of 1 to 10, and I tried removing every second number, and then third
I should get 1, 3, 5, 7, 9 after removing every second number,
and 1, 3, 7, 9 after removing every third (only one number)
for i in range(repeatAmount):
multiple = int(input())
del numberVar[1::multiple]
print(numberVar)
This code returns [1, 3, 5, 7, 9] after removing every second number, which is correct
But then returns [1, 5, 7] after removing every third number
I have no idea what's going wrong
Change this line
del numberVar[1::multiple]
to this line:
del numberVar[multiple-1::multiple]
Output: [1, 3, 7, 9]
In your loop, you referenced index #1 both times as your starting index, hence you removed the first and fourth elements (3 and 9) in the second iteration of the loop.
Related
I have a few vectors.
I want to find all permutations of each vector.
It works reasonably well, when the values are unique but if there are reappearing values it messes up.
I have the following vectors
vector<string> present = {"Schaukelpferd","Schaukelpferd","Puppe","Puppe"};
vector<string> children = {"Jan","Tim","Alex","Daniel"};
vector<int> houses = {4,5,5,5};
I am sorting the before using next_permutation()
sort(present.begin(),present.end());
sort(children.begin(),children.end());
sort(houses.begin(),houses.end());
do {
present_perm.push_back(present);
} while (next_permutation(present.begin(), present.end()));
do {
children_perm.push_back(children);
} while (next_permutation(children.begin(), children.end()));
do {
houses_perm.push_back(houses);
} while (next_permutation(houses.begin(), houses.end()));
children works good, but present as well as houses doesn't work as expected
children returns 24 permutation, as expected, present returns only 6 and houses returns only 4. I would expect all to return 24 because all vectors have 4 elements (4! = 24).
Consider the four integer values 4, 5, 5, 5. The four possible permutations are 4, 5, 5, 5 and 5, 4, 5, 5 and 5, 5, 4, 5 and 5, 5, 5, 4. That's it. The three 5s have the same value, so they cannot be distinguished from each other. The algorithm doesn't keep track of which of those values originally came before the other; they're the same. The same thing applies to present: there are three distinct values, not four.
So, my goal is to capture data in a buffer.
I need speed and I just need a fixed size so I was thinking that a circular array would be the best.
But what I want to do is at each step to:
first, overwrite the latest information in the array with the newest that just arrived
next, using the all array starting from the oldest to the newest
repeat
I have difficulty to see how to handle the second step in C++ while being efficient. Or maybe something else than a circular array would be better? Any advise or point of view is welcome.
To have something more graphic:
for step in steps:
(current writing position = 2)
current buffer = [8, 9, 3, 4, 5, 6, 7]
new info = 10
overwrite buffer(new info)
new buffer = [8, 9, 10, 4, 5, 6, 7]
current writing position += 1 //(3)
array to use = [4, 5, 6, 7, 8, 9, 10]
function(array to use)
(I used integer following each other to see the chronology of each information in the buffer)
What I am thinking about is to copy the last part and first part and then concatenate them:
std::vector<int> buffer{8, 9, 10, 4, 5, 6, 7};
std::vector<int> oldest(&buffer[3],&buffer[6]);
std::vector<int> youngest(&buffer[0],&buffer[2]);
oldest.insert( oldest.end(), youngest.begin(), youngest.end() );
function(oldest)
If you know something that would be quicker please tell me.
If you really need speed you should not copy elements but use the index information you already have to access the elements in the right order.
So the handling function would just need a pointer to the array (or reference to std::vector), know the size and the current working pos.
// process from working pos to end of buffer
for(int i = current_pos; i < buffer_size; ++i) {
processElement(new_buffer [i]);
}
// process the remainder from begin to working pos
for(int i = 0; i < curent_pos; ++i) {
processElement(new_buffer [i]);
}
This should not be to hard to inplement as your working position marks both, the begin and end of your data to process.
This approach reduces the copy overhead n-fold where n is the number of extra array elements + 1 used.
Example: array with 2 extra elements
Note, in this case, the oldest value is on the left, the function has been called with pointer to arr[0] (start_pos = 0)
arr == [3, 4, 5, 6, 7, 8, 9, x, x]
now, lets insert the new value 10
arr == [3, 4, 5, 6, 7, 8, 9, 10, x]
start_pos += 1
call function with pointer to the second element (the old 3 won't be used)
function(arr + start_pos)
and now add the 11 and increment the working position (the old 4 won't be used)
arr == [3, 4, 5, 6, 7, 8, 9, 10, 11]
start_pos += 1
function(arr + start_pos)
Now, the array is full.
And only now it is needed to copy the last elements to the begin of the array (after the start_pos to the end) and set working_pos back to 0
depending on the number of extra elements this needs to be done only every 10th, 100th or even 1000th iteration !
result of copying would be:
arr == [6, 7, 8, 9, 10, 11, 9, 10, 11]
*
start_pos = -1 // prepare for the +1 in regular iteration.
next added value (12) will overwrite the * value
arr == [6, 7, 8, 9, 10, 11, 12, 10, 11]
start_pos += 1 // is 0 now
function(arr + start_pos)
Of course, you need one variable to determine the pos to insert the new element behind the other val or you derive from start_pos + nElemsToProcess
If your function() does only take std containers it is probably not the right choice to met the need for speed.
I have a set of lists that I want to compare firstly the sum values of the lists and then individual elements in the event of two or more lists having the same value.
my_list1 = [2, 3, 2, 4, 5]
my_list2 = [1, 3, 2, 3, 2]
my_list3 = [1, 1, 2, 2, 2]
my_list4 = [3, 2, 2, 4, 5]
Logic testing for an outright winner is fine but the problem I am having is isolating the lists in the event of a draw – So in the scenario above my_list1 and my_list4 would be isolated for further logic testing as their totals both come to 16.
This is what I have so far
my_list1=[1,1,2,2,2]
my_list2=[1,1,1,1,2]
my_list3=[2,2,1,1,2]
my_list1Total=sum(my_list1)
my_list2Total=sum(my_list2)
my_list3Total=sum(my_list3)
if my_list1Total>my_list2Total and my_list1Total>my_list3Total:
print("List one has the higest score")
elif my_list2Total>my_list1Total and my_list2Total>my_list3Total:
print("List two has the higest score")
elif my_list3Total>my_list2Total and my_list3Total>my_list1Total:
print("List three has the higest score")
else:
print("Draw")
##so now I want to compare the lists with the same total but this time by the first element in the list. In this case it would be my_list1[0] and my_list3[0] that would be compared next. The winner having the highest value in position 0 of the drawing lists
I suggest creating a single list which holds all of your lists. Then you can use max on that list to find the largest element. Or, if you want the index of the list and not just its value, you can write a max-like method and use that instead.
#like the built-in function `max`,
#but returns the index of the largest element
#instead of the largest element itself.
def index_of_max(seq, key=lambda item:item):
return max(range(len(seq)), key=lambda idx: key(seq[idx]))
lists = [
[2, 3, 2, 4, 5],
[1, 3, 2, 3, 2],
[1, 1, 2, 2, 2],
[3, 2, 2, 4, 5]
]
idx = index_of_max(lists, key=lambda item: (sum(item), item[0]))
#add one to this result because Python lists are zero indexed,
#but the original numbering scheme started at one.
print "List # {} is largest.".format(idx+1)
Result:
List # 4 is largest.
A little explanation about key: it's a function that you pass to max, that it uses to determine the comparative value of two items in the sequence. It calls key(someItem) on both items, and whichever item has a larger result, is considered the maximum item between the two of them. The key function I used here returns a tuple. Due to the way tuple comparison works in Python, comparison is done by sum first, then using the first element of each list as a tie breaker.
If you're thinking "but what if the first elements are also the same? I want to use each following item as a tie breaker", then you can modify the key to compare all of them in turn.
idx = index_of_max(lists, key=lambda item: [sum(item)]+item)
I want to look in an array of elements. If an element exceeds a certain value x, replace it with another value y. It could be a bunch of elements that need to be replaced. Is there a function (code) to do this at once. I don't want to use for loop.
Does the any() function help here?
Thanks
I really don't know how one could possibly achieve such a thing without the if statement.
Don't know about any() but I gave it a try with map since you don't want a for loop. But, do note that the complexity order (Big O) is still n.
>>> array = [1, 2, 3, 4, 2, -2, -3, 8, 3, 0]
>>> array = map(lambda x: x if x < 3 else 2, array)
>>> array
[1, 2, 2, 2, 2, -2, -3, 2, 2, 0]
Basically, x if x < 3 else 2 works like If an element exceeds a certain value x, replaces it with another value y.
So I've been playing around with python and noticed something that seems a bit odd. The semantics of -1 in selecting from a list don't seem to be consistent.
So I have a list of numbers
ls = range(1000)
The last element of the list if of course ls[-1] but if I take a sublist of that so that I get everything from say the midpoint to the end I would do
ls[500:-1]
but this does not give me a list containing the last element in the list, but instead a list containing everything UP TO the last element. However if I do
ls[0:10]
I get a list containing also the tenth element (so the selector ought to be inclusive), why then does it not work for -1.
I can of course do ls[500:] or ls[500:len(ls)] (which would be silly). I was just wondering what the deal with -1 was, I realise that I don't need it there.
In list[first:last], last is not included.
The 10th element is ls[9], in ls[0:10] there isn't ls[10].
If you want to get a sub list including the last element, you leave blank after colon:
>>> ll=range(10)
>>> ll
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> ll[5:]
[5, 6, 7, 8, 9]
>>> ll[:]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
I get consistent behaviour for both instances:
>>> ls[0:10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> ls[10:-1]
[10, 11, 12, 13, 14, 15, 16, 17, 18]
Note, though, that tenth element of the list is at index 9, since the list is 0-indexed. That might be where your hang-up is.
In other words, [0:10] doesn't go from index 0-10, it effectively goes from 0 to the tenth element (which gets you indexes 0-9, since the 10 is not inclusive at the end of the slice).
It seems pretty consistent to me; positive indices are also non-inclusive. I think you're doing it wrong. Remembering that range() is also non-inclusive, and that Python arrays are 0-indexed, here's a sample python session to illustrate:
>>> d = range(10)
>>> d
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> d[9]
9
>>> d[-1]
9
>>> d[0:9]
[0, 1, 2, 3, 4, 5, 6, 7, 8]
>>> d[0:-1]
[0, 1, 2, 3, 4, 5, 6, 7, 8]
>>> len(d)
10
when slicing an array;
ls[y:x]
takes the slice from element y upto and but not including x. when you use the negative indexing it is equivalent to using
ls[y:-1] == ls[y:len(ls)-1]
so it so the slice would be upto the last element, but it wouldn't include it (as per the slice)
-1 isn't special in the sense that the sequence is read backwards, it rather wraps around the ends. Such that minus one means zero minus one, exclusive (and, for a positive step value, the sequence is read "from left to right".
so for i = [1, 2, 3, 4], i[2:-1] means from item two to the beginning minus one (or, 'around to the end'), which results in [3].
The -1th element, or element 0 backwards 1 is the last 4, but since it's exclusive, we get 3.
I hope this is somewhat understandable.