e.g.:
from :
"[1,2,3]"to [1,2,3]
as the function int() makes a "5" a 5
The json and ast packages can help with parsing like this. In this case try:
import json
foo = json.loads("[1,2,3]")
or
import ast
foo = ast.literal_eval("[1,2,3]")
#Sid asks an important question in the comments:
Why not use eval() as it is baked in and would not require the import?
While it is technically true that:
foo = eval("[1,2,3]")
also produces the desired result in this case, #AndyLester importantly reminds us that eval() can be dangerous. Specifically eval() allows for execution of code not just parsing of literals. If we imagine that the following could be any arbitrary block of python and someone could pollute our input with it:
"print('Here be Dragons')"
Then the first two methods will throw exceptions:
foo = json.loads("print('Here be Dragons')")
>>>json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
and
foo = ast.literal_eval("print('Here be Dragons')")
>>>ValueError: malformed node or string:
While the third does
foo = eval("print('Here be Dragons')")
>>>Here be Dragons
our input was executed (dangerous) rather than simply parsed and worse, foo also is still None as print() has no return value.
This will correctly parse your list
k = '[1,2,3]'
list(map(lambda x: int(x), k[1:-1].split(',')))
Yields:
[1, 2, 3]
I am having trouble with the second function in converting it back to the original string. I see what the issue is as when I call previous function, the tuple has a string and an int. So I assume I must convert that int to a string. But based on the code I wrote, I am not sure where to convert it. Hopefully, I am on the right track with this. My professor is very strict when it comes to certain things I cannot use any built-ins. Thank you. Any help is appreciated.
EDIT
Will put code back soon
My suggestion is in this case to use print statements for debugging.
def rldecode(rlencode):
decodedString = ""
L = []
for i in rlencode:
counter = 0
occurrence = i[1] # tuple (item, occurrence) == positions (0, 1)
for j in range(occurrence):
L.append(i[0])
return ''.join(L)
I was at a meetup recently and one of the talks was about how you can use Webpack to require just the pieces of a package that you need. I believe that it is called tree shaking. I was wondering if there is a way to do this without Webpack? For instance can you specify exactly the pieces of code you need rather than the whole node module.
Any information about this would be great. I am just looking to learn something new.
Cheers,
There's a couple pretty simple ways:
In ES6, you can do what is called destructuring.
Here's an example with arrays:
var a, b, rest;
[a, b] = [10, 20];
console.log(a);
// expected output: 10
console.log(b);
// expected output: 20
[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(rest);
// expected output: [30,40,50]
This is destructuring by index, where a = array[0], b=array of index 1 (hyperlink barred bracket format), etc... Notice the ... operator, called the spread operator in ES6. Here is a link to that if you are curious about what it does, or how to use it.
You can also do the same with objects, consider:
const someRandomObject = {
a: 1,
b: 2,
};
const {a} = someRandomObject;
console.log(a) // expected output: 1
You are destructing, by name, only the properties you need from the object, so you are not pulling in a bunch of unused stuff. If you are not using ES6, you can do something similar with:
const someRandomObject = {
a: 1,
b: 2,
};
const a = someRandomObject.b;
console.log(a) // expected output: 2
Same thing as above, you are pulling out of someRandomObject the property you want, and nothing else. Note that the above way is pulling the value on the right side, so the name of the variable does not matter. These two ways are functionally equivalent (I believe).
From the Mozilla Developer Network:
[1,4,9].map(Math.sqrt)
will yield:
[1,2,3]
Why then does this:
['1','2','3'].map(parseInt)
yield this:
[1, NaN, NaN]
I have tested in Firefox 3.0.1 and Chrome 0.3 and just as a disclaimer, I know this is not cross-browser functionality (no IE).
I found out that the following will accomplish the desired effect. However, it still doesn’t explain the errant behavior of parseInt.
['1','2','3'].map(function(i){return +i;}) // returns [1,2,3]
The callback function in Array.map has three parameters:
From the same Mozilla page that you linked to:
callback is invoked with three arguments: the value of the element, the index of the element, and the Array object being traversed."
So if you call a function parseInt which actually expects two arguments, the second argument will be the index of the element.
In this case, you ended up calling parseInt with radix 0, 1 and 2 in turn. The first is the same as not supplying the parameter, so it defaulted based on the input (base 10, in this case). Base 1 is an impossible number base, and 3 is not a valid number in base 2:
parseInt('1', 0); // OK - gives 1
parseInt('2', 1); // FAIL - 1 isn't a legal radix
parseInt('3', 2); // FAIL - 3 isn't legal in base 2
So in this case, you need the wrapper function:
['1','2','3'].map(function(num) { return parseInt(num, 10); });
or with ES2015+ syntax:
['1','2','3'].map(num => parseInt(num, 10));
(In both cases, it's best to explicitly supply a radix to parseInt as shown, because otherwise it guesses the radix based on the input. In some older browsers, a leading 0 caused it to guess octal, which tended to be problematic. It will still guess hex if the string starts with 0x.)
map is passing along a 2nd argument, which is (in many of the cases) messing up parseInt's radix parameter.
If you're using underscore you can do:
['10','1','100'].map(_.partial(parseInt, _, 10))
Or without underscore:
['10','1','100'].map(function(x) { return parseInt(x, 10); });
You could solve this problem using Number as iteratee function:
var a = ['0', '1', '2', '10', '15', '57'].map(Number);
console.log(a);
Without the new operator, Number can be used to perform type conversion. However, it differs from parseInt: it doesn't parse the string and returns NaN if the number cannot be converted. For instance:
console.log(parseInt("19asdf"));
console.log(Number("19asf"));
I'm going to wager that it's something funky going on with the parseInt's 2nd parameter, the radix. Why it is breaking with the use of Array.map and not when you call it directly, I do not know.
// Works fine
parseInt( 4 );
parseInt( 9 );
// Breaks! Why?
[1,4,9].map( parseInt );
// Fixes the problem
[1,4,9].map( function( num ){ return parseInt( num, 10 ) } );
You can use arrow function ES2015/ES6 and just pass number to the parseInt. Default value for radix will be 10
[10, 20, 30].map(x => parseInt(x))
Or you can explicitly specify radix for better readability of your code.
[10, 20, 30].map(x => parseInt(x, 10))
In example above radix explicitly set to 10
another (working) quick fix :
var parseInt10 = function(x){return parseInt(x, 10);}
['0', '1', '2', '10', '15', '57'].map(parseInt10);
//[0, 1, 2, 10, 15, 57]
You can solve that issue like this:
array.map(x => parseInt(x))
Example:
var arr = ["3", "5", "7"];
console.log(
arr.map(x => parseInt(x))
);
parseInt IMHO should be avoided for this very reason. You can wrap it to make it more safe in these contexts like this:
const safe = {
parseInt: (s, opt) => {
const { radix = 10 } = opt ? opt : {};
return parseInt(s, radix);
}
}
console.log( ['1','2','3'].map(safe.parseInt) );
console.log(
['1', '10', '11'].map(e => safe.parseInt(e, { radix: 2 }))
);
lodash/fp caps iteratee arguments to 1 by default to avoid these gotchas. Personally I have found these workarounds to create as many bugs as they avoid. Blacklisting parseInt in favor of a safer implementation is, I think, a better approach.
I need to write a method in Scala that overrides the toString method. I wrote it but I also have to check that if there is an element that is '1' I will change it to 'a', else write the list as it is with the string method. Any suggestions how this can be done?
What error are you getting? seems to work for me
val l = List(1, 2, 3)
println(this)
override def toString(): String = {
val t = l.map({
case 1 => "a"
case x => x
})
t.toString
}
getting List(a, 2, 3) printed out
I see from the comments on your question that list is a List[List[Int]].
Look at the beginning of your code:
list.map { case 1 => 'a'; case x => x}
map expects a function that takes an element of list as a parameter - a List[Int], in your case. But your code works directly on Int.
With this information, it appears that the error you get is entirely correct: you declared a method that expects an Int, but you pass a List[Int] to it, which is indeed a type mismatch.
Try this:
list.map {_.map { case 1 => 'a'; case x => x}}
This way, the function you defined to transform 1 to a and leave everything else alone is applied to list's sublists, and this type-checks: you're applying a function that expects an Int to an Int.