我创建了一个函数,可以生成一个连续递增的字母列表。 A,B,C ......,Z.在Z之后,它转到AA,AB,AC ...... AZ。这种模式重复。这类似于MS Excel的列名。目前,此函数生成一个有限的字母表列表。
_column_name_generator() = ['A', 'B', ..., 'AA', 'AB', ..., 'BA', 'BB', ..., 'CV']
然后我可以结合一些有限列表迭代它,例如0-10。请参阅下面的代码。我想要的是创建一个生成器,它将为我提供一个无限长的递增字母表列表。
import string
def _column_name_generator():
column_names = []
for x in range(0, 100):
if x < 26:
column_names.append(string.ascii_uppercase[x % 26])
else:
column_names.append(column_names[x/26 - 1] + string.ascii_uppercase[x % 26])
return column_names
container = []
for column_name, num in zip(_column_name_generator(), range(0, 10)):
container.append(column_name + str(num))
print _column_name_generator()
print container
container = ['A0', 'B1', 'C2', 'D3', 'E4', 'F5', 'G6', 'H7', 'I8', 'J9']
答案 0 :(得分:8)
每次收益column_names
的最后一个元素,并使用itertools.count
代替range
来提供无限增加:
import itertools
def _column_name_generator():
column_names = []
for x in itertools.count():
if x < 26:
column_names.append(string.ascii_uppercase[x % 26])
else:
column_names.append(column_names[x/26 - 1] + string.ascii_uppercase[x % 26])
yield column_names[-1]
更好的解决方案,改变原始代码但忽略了column_names
内存消耗列表中的需求,将是
import itertools, string
def _column_name_generator():
for i in itertools.count(1):
for p in itertools.product(string.ascii_uppercase, repeat=i):
yield ''.join(p)
从i
开始1
A
B
时,它基本上遍历长度为C
的大写ascii字母(每个可能的序列)的乘积, <?php
class WpProQuiz_Controller_Toplist extends WpProQuiz_Controller_Controller
{
public function route()
{
$quizId = $_GET['id'];
$action = isset($_GET['action']) ? $_GET['action'] : 'show';
switch ($action) {
default:
$this->showAdminToplist($quizId);
break;
}
}
private function showAdminToplist($quizId)
{
if (!current_user_can('wpProQuiz_toplist_edit')) {
wp_die(__('You do not have sufficient permissions to access this page.'));
}
$view = new WpProQuiz_View_AdminToplist();
$quizMapper = new WpProQuiz_Model_QuizMapper();
$quiz = $quizMapper->fetch($quizId);
$view->quiz = $quiz;
$view->show();
}
public function getAddToplist(WpProQuiz_Model_Quiz $quiz)
{
$userId = get_current_user_id();
if (!$quiz->isToplistActivated()) {
return null;
}
$data = array(
'userId' => $userId,
'token' => wp_create_nonce('wpProQuiz_toplist'),
'canAdd' => $this->preCheck($quiz->getToplistDataAddPermissions(), $userId),
);
if ($quiz->isToplistDataCaptcha() && $userId == 0) {
$captcha = WpProQuiz_Helper_Captcha::getInstance();
if ($captcha->isSupported()) {
$data['captcha']['img'] = WPPROQUIZ_CAPTCHA_URL . '/' . $captcha->createImage();
$data['captcha']['code'] = $captcha->getPrefix();
}
}
return $data;
}
private function handleAddInToplist(WpProQuiz_Model_Quiz $quiz)
{
if (!wp_verify_nonce($this->_post['token'], 'wpProQuiz_toplist')) {
return array('text' => __('An error has occurred.', 'wp-pro-quiz'), 'clear' => true);
}
if (!isset($this->_post['points']) || !isset($this->_post['totalPoints'])) {
return array('text' => __('An error has occurred.', 'wp-pro-quiz'), 'clear' => true);
}
$quizId = $quiz->getId();
$userId = get_current_user_id();
$points = (int)$this->_post['points'];
$totalPoints = (int)$this->_post['totalPoints'];
$name = !empty($this->_post['name']) ? trim($this->_post['name']) : '';
$email = !empty($this->_post['email']) ? trim($this->_post['email']) : '';
$ip = filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP);
$captchaAnswer = !empty($this->_post['captcha']) ? trim($this->_post['captcha']) : '';
$prefix = !empty($this->_post['prefix']) ? trim($this->_post['prefix']) : '';
$quizMapper = new WpProQuiz_Model_QuizMapper();
$toplistMapper = new WpProQuiz_Model_ToplistMapper();
if ($quiz == null || $quiz->getId() == 0 || !$quiz->isToplistActivated()) {
return array('text' => __('An error has occurred.', 'wp-pro-quiz'), 'clear' => true);
}
if (!$this->preCheck($quiz->getToplistDataAddPermissions(), $userId)) {
return array('text' => __('An error has occurred.', 'wp-pro-quiz'), 'clear' => true);
}
$numPoints = $quizMapper->sumQuestionPoints($quizId);
if ($totalPoints > $numPoints || $points > $numPoints) {
return array('text' => __('An error has occurred.', 'wp-pro-quiz'), 'clear' => true);
}
$clearTime = null;
if ($quiz->isToplistDataAddMultiple()) {
$clearTime = $quiz->getToplistDataAddBlock() * 60;
}
if ($userId > 0) {
if ($toplistMapper->countUser($quizId, $userId, $clearTime)) {
return array('text' => __('You can not enter again.', 'wp-pro-quiz'), 'clear' => true);
}
$user = wp_get_current_user();
$email = $user->user_email;
$name = $user->display_name;
} else {
if ($toplistMapper->countFree($quizId, $name, $email, $ip, $clearTime)) {
return array('text' => __('You can not enter again.', 'wp-pro-quiz'), 'clear' => true);
}
if (empty($name) || empty($email) || filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
return array('text' => __('No name or e-mail entered.', 'wp-pro-quiz'), 'clear' => false);
}
if (strlen($name) > 15) {
return array('text' => __('Your name can not exceed 15 characters.', 'wp-pro-quiz'), 'clear' => false);
}
if ($quiz->isToplistDataCaptcha()) {
$captcha = WpProQuiz_Helper_Captcha::getInstance();
if ($captcha->isSupported()) {
if (!$captcha->check($prefix, $captchaAnswer)) {
return array('text' => __('You entered wrong captcha code.', 'wp-pro-quiz'), 'clear' => false);
}
}
}
}
$toplist = new WpProQuiz_Model_Toplist();
$toplist->setQuizId($quizId)
->setUserId($userId)
->setDate(time())
->setName($name)
->setEmail($email)
->setPoints($points)
->setResult(round($points / $totalPoints * 100, 2))
->setIp($ip);
$toplistMapper->save($toplist);
return true;
}
private function preCheck($type, $userId)
{
switch ($type) {
case WpProQuiz_Model_Quiz::QUIZ_TOPLIST_TYPE_ALL:
return true;
case WpProQuiz_Model_Quiz::QUIZ_TOPLIST_TYPE_ONLY_ANONYM:
return $userId == 0;
case WpProQuiz_Model_Quiz::QUIZ_TOPLIST_TYPE_ONLY_USER:
return $userId > 0;
}
return false;
}
public static function ajaxAdminToplist($data)
{
if (!current_user_can('wpProQuiz_toplist_edit')) {
return json_encode(array());
}
$toplistMapper = new WpProQuiz_Model_ToplistMapper();
$j = array('data' => array());
$limit = (int)$data['limit'];
$start = $limit * ($data['page'] - 1);
$isNav = isset($data['nav']);
$quizId = $data['quizId'];
if (isset($data['a'])) {
switch ($data['a']) {
case 'deleteAll':
$toplistMapper->delete($quizId);
break;
case 'delete':
if (!empty($data['toplistIds'])) {
$toplistMapper->delete($quizId, $data['toplistIds']);
}
break;
}
$start = 0;
$isNav = true;
}
$toplist = $toplistMapper->fetch($quizId, $limit, $data['sort'], $start);
foreach ($toplist as $tp) {
$j['data'][] = array(
'id' => $tp->getToplistId(),
'name' => $tp->getName(),
'email' => $tp->getEmail(),
'type' => $tp->getUserId() ? 'R' : 'UR',
'date' => WpProQuiz_Helper_Until::convertTime($tp->getDate(),
get_option('wpProQuiz_toplistDataFormat', 'Y/m/d g:i A')),
'points' => $tp->getPoints(),
'result' => $tp->getResult()
);
}
if ($isNav) {
$count = $toplistMapper->count($quizId);
$pages = ceil($count / $limit);
$j['nav'] = array(
'count' => $count,
'pages' => $pages ? $pages : 1
);
}
return json_encode($j);
}
public static function ajaxAddInToplist($data)
{
// workaround ...
$_POST = $_POST['data'];
$ctn = new WpProQuiz_Controller_Toplist();
$quizId = isset($data['quizId']) ? $data['quizId'] : 0;
$prefix = !empty($data['prefix']) ? trim($data['prefix']) : '';
$quizMapper = new WpProQuiz_Model_QuizMapper();
$quiz = $quizMapper->fetch($quizId);
$r = $ctn->handleAddInToplist($quiz);
if ($quiz->isToplistActivated() && $quiz->isToplistDataCaptcha() && get_current_user_id() == 0) {
$captcha = WpProQuiz_Helper_Captcha::getInstance();
if ($captcha->isSupported()) {
$captcha->remove($prefix);
$captcha->cleanup();
if ($r !== true) {
$r['captcha']['img'] = WPPROQUIZ_CAPTCHA_URL . '/' . $captcha->createImage();
$r['captcha']['code'] = $captcha->getPrefix();
}
}
}
if ($r === true) {
$r = array('text' => __('You signed up successfully.', 'wp-pro-quiz'), 'clear' => true);
}
return json_encode($r);
}
public static function ajaxShowFrontToplist($data)
{
// workaround ...
$_POST = $_POST['data'];
$quizIds = empty($data['quizIds']) ? array() : array_unique((array)$data['quizIds']);
$toplistMapper = new WpProQuiz_Model_ToplistMapper();
$quizMapper = new WpProQuiz_Model_QuizMapper();
$j = array();
foreach ($quizIds as $quizId) {
$quiz = $quizMapper->fetch($quizId);
if ($quiz == null || $quiz->getId() == 0) {
continue;
}
$toplist = $toplistMapper->fetch($quizId, $quiz->getToplistDataShowLimit(), $quiz->getToplistDataSort());
foreach ($toplist as $tp) {
$j[$quizId][] = array(
'name' => $tp->getName(),
'date' => WpProQuiz_Helper_Until::convertTime($tp->getDate(),
get_option('wpProQuiz_toplistDataFormat', 'Y/m/d g:i A')),
'points' => $tp->getPoints(),
'result' => $tp->getResult()
);
}
}
return json_encode($j);
}
}
)。
答案 1 :(得分:1)
一种不那么pythonic的方式
正如你的问题所暗示的那样,一种方法是除以26将每个步骤的余数转换成一个字母,直到除法返回0.使用%
(modulo)得到余数,//
(楼层划分)更新下一步的值。这可能是代码:
numberOfElements = 100
letters = []
for counter in range(numberOfElements):
i = counter
newCharacter = i % 26
i //= 26
s = "" +chr(newCharacter + ord('A') )
while i != 0:
newCharacter = i % 26
i //= 26
s = chr(newCharacter + ord('A') ) + s
letters.append(s)
print letters
结果:
['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','BA ”, 'BB','BC','BD','BE','BF','BG','BH','BI','BJ','BK','BL', 'BM','BN','BO','BP','BQ','BR','BS','BT','BU','BV','BW', 'BX','BY','BZ','CA','CB','CC','CD','CE','CF','CG','CH', 'CI','CJ','CK','CL','CM','CN','CO','CP','CQ','CR','CS', 'CT','CU','CV','CW','CX','CY','CZ','DA','DB','DC','DD', 'DE','DF','DG','DH','DI','DJ','DK','DL','DM','DN','DO', 'DP','DQ','DR','DS','DT','DU','DV']