Python __repr__ 方法:写一个 JS 等价物?
Python __repr__ method: writing a JS equivalent?
我正在学习一个关于算法和数据结构的短期初学者课程。导师的语言是Python;我正在将代码示例转换为 JavasScript。到目前为止,还不错。
我正在处理链表。讲师使用 Python 的 __repr__()
方法测试代码。经过几天的反复试验,我有了一个有效的 JS 解决方案,但它与 Python 代码并不完全相同。我想知道是否有更好的方法来实现我提供的 JS 代码以及 Python 代码。
Python
# class LinkedList and its methods are presumed to exist
def __repr__(self):
nodes = []
current = self.head
while current:
if current is self.head:
nodes.append("[Head: %s]" % current.data)
elif current.next_node is None:
nodes.append("[Tail: %s]" % current.data)
else
nodes.append("[%s]" % current.data)
current = current.next_node
return '-> '.join(nodes)
# running script
>>> l = LinkedList()
>>> l.add(1)
>>> l.add(2)
>>> l.add(3)
>>> l
[Head: 3]-> [2]-> [Tail: 1] # output
>>>
JS
// class LinkedList and its methods are presumed to exist
repr () {
let nodes = "";
let current = this.head;
while (current) {
if (current === this.head) {
nodes = `Head: ${current.data}-> `;
} else if (current.nextNode === null) {
nodes += `Tail: ${current.data}`;
} else {
nodes += `${current.data}-> `;
}
current = current.nextNode;
}
return nodes;
// running the script
let l = LinkedList();
l.add(1);
l.add(2);
l.add(3);
let result = l.repr();
console.log(result); // Head: 3-> 2-> Tail: 1
同样,这两个片段只会 运行 在链表算法的完整实现中,但它们确实有效。
我所做的尝试:我尝试使用 JS toString()
、append()
和 appendChild()
,但它们太难了,我无法理解如何最好地使用它们,尤其是作为最后两个修改DOM。我确定有更好的方法来实现相当于 Python __repr__()
; 的 JS;我想知道怎么做。
更接近的实现将使用 toString
方法。当需要转换为字符串时,将隐式调用此方法。 Python 实际上有两种方法,目的略有不同:__repr__
和 __str__
。 JavaScript.
中没有这种区别
此外,我们应该意识到 Python 的 print
将隐式调用 __repr__
,这不是 console.log
的工作方式。因此,对于 console.log
,您必须强制转换为字符串。
下面是给定的 Python 代码最直译的方式(我将 运行 脚本所需的 类 添加到脚本中):
class Node {
constructor(data, next=null) {
this.data = data;
this.next_node = next;
}
}
class LinkedList {
constructor() {
this.head = null;
}
add(data) {
this.head = new Node(data, this.head);
}
toString() {
let nodes = [];
let current = this.head;
while (current) {
if (current === this.head) {
nodes.push(`[Head: ${current.data}]`);
} else if (current.next_node === null) {
nodes.push(`[Tail: ${current.data}]`);
} else {
nodes.push(`[${current.data}]`);
}
current = current.next_node;
}
return nodes.join('-> ');
}
}
// running script
let l = new LinkedList();
l.add(1);
l.add(2);
l.add(3);
// Force conversion to string
console.log(`${l}`); // [Head: 3]-> [2]-> [Tail: 1]
就个人而言,我会进行以下更改(未反映在 Python 版本中):
- 生成没有“Head”和“Tail”以及其他“修饰”字样的输出。这对我来说太冗长了。只输出分隔值。
- 使列表实例可迭代,实现
Symbol.iterator
方法(在 Python 中:__iter__
)。然后使用它来实现 toString
方法。
- 允许列表构造函数采用任意数量的值来填充列表。
这导致以下版本:
class Node {
constructor(data, next=null) {
this.data = data;
this.next = next;
}
}
class LinkedList {
constructor(...values) { // Accept any number of values
this.head = null;
// Populate in reverse order
for (let data of values.reverse()) this.add(data);
}
add(data) {
this.head = new Node(data, this.head);
}
// Make lists iterable
*[Symbol.iterator]() {
let current = this.head;
while (current) {
yield current.data;
current = current.next;
}
}
toString() {
// Array.from triggers the above method
return Array.from(this).join("→");
}
}
// Provide the desired values immediately:
let l = new LinkedList(3, 2, 1);
console.log(`${l}`); // 3→2→1
我正在学习一个关于算法和数据结构的短期初学者课程。导师的语言是Python;我正在将代码示例转换为 JavasScript。到目前为止,还不错。
我正在处理链表。讲师使用 Python 的 __repr__()
方法测试代码。经过几天的反复试验,我有了一个有效的 JS 解决方案,但它与 Python 代码并不完全相同。我想知道是否有更好的方法来实现我提供的 JS 代码以及 Python 代码。
Python
# class LinkedList and its methods are presumed to exist
def __repr__(self):
nodes = []
current = self.head
while current:
if current is self.head:
nodes.append("[Head: %s]" % current.data)
elif current.next_node is None:
nodes.append("[Tail: %s]" % current.data)
else
nodes.append("[%s]" % current.data)
current = current.next_node
return '-> '.join(nodes)
# running script
>>> l = LinkedList()
>>> l.add(1)
>>> l.add(2)
>>> l.add(3)
>>> l
[Head: 3]-> [2]-> [Tail: 1] # output
>>>
JS
// class LinkedList and its methods are presumed to exist
repr () {
let nodes = "";
let current = this.head;
while (current) {
if (current === this.head) {
nodes = `Head: ${current.data}-> `;
} else if (current.nextNode === null) {
nodes += `Tail: ${current.data}`;
} else {
nodes += `${current.data}-> `;
}
current = current.nextNode;
}
return nodes;
// running the script
let l = LinkedList();
l.add(1);
l.add(2);
l.add(3);
let result = l.repr();
console.log(result); // Head: 3-> 2-> Tail: 1
同样,这两个片段只会 运行 在链表算法的完整实现中,但它们确实有效。
我所做的尝试:我尝试使用 JS toString()
、append()
和 appendChild()
,但它们太难了,我无法理解如何最好地使用它们,尤其是作为最后两个修改DOM。我确定有更好的方法来实现相当于 Python __repr__()
; 的 JS;我想知道怎么做。
更接近的实现将使用 toString
方法。当需要转换为字符串时,将隐式调用此方法。 Python 实际上有两种方法,目的略有不同:__repr__
和 __str__
。 JavaScript.
此外,我们应该意识到 Python 的 print
将隐式调用 __repr__
,这不是 console.log
的工作方式。因此,对于 console.log
,您必须强制转换为字符串。
下面是给定的 Python 代码最直译的方式(我将 运行 脚本所需的 类 添加到脚本中):
class Node {
constructor(data, next=null) {
this.data = data;
this.next_node = next;
}
}
class LinkedList {
constructor() {
this.head = null;
}
add(data) {
this.head = new Node(data, this.head);
}
toString() {
let nodes = [];
let current = this.head;
while (current) {
if (current === this.head) {
nodes.push(`[Head: ${current.data}]`);
} else if (current.next_node === null) {
nodes.push(`[Tail: ${current.data}]`);
} else {
nodes.push(`[${current.data}]`);
}
current = current.next_node;
}
return nodes.join('-> ');
}
}
// running script
let l = new LinkedList();
l.add(1);
l.add(2);
l.add(3);
// Force conversion to string
console.log(`${l}`); // [Head: 3]-> [2]-> [Tail: 1]
就个人而言,我会进行以下更改(未反映在 Python 版本中):
- 生成没有“Head”和“Tail”以及其他“修饰”字样的输出。这对我来说太冗长了。只输出分隔值。
- 使列表实例可迭代,实现
Symbol.iterator
方法(在 Python 中:__iter__
)。然后使用它来实现toString
方法。 - 允许列表构造函数采用任意数量的值来填充列表。
这导致以下版本:
class Node {
constructor(data, next=null) {
this.data = data;
this.next = next;
}
}
class LinkedList {
constructor(...values) { // Accept any number of values
this.head = null;
// Populate in reverse order
for (let data of values.reverse()) this.add(data);
}
add(data) {
this.head = new Node(data, this.head);
}
// Make lists iterable
*[Symbol.iterator]() {
let current = this.head;
while (current) {
yield current.data;
current = current.next;
}
}
toString() {
// Array.from triggers the above method
return Array.from(this).join("→");
}
}
// Provide the desired values immediately:
let l = new LinkedList(3, 2, 1);
console.log(`${l}`); // 3→2→1